Trying to make a ball bounce on the screen in processing using classes - processing

I am working on making a single ball bounce all over the screen but I have an issue with making the ball bounce the bounce() function is responsible for making the ball bounce but I run into an array out of bounds exception despite only going through 1 element in the array. I have provided the code below. This code utilizes 2 classes (Ball_Usage and Ball).
Ball_Usage code:
Ball ball1;
void setup(){
size(500,500);
ball1 = new Ball();
}
void draw(){
background(255);
ball1.bounce();
}
Ball:
class Ball{
float [] xPos = {};
float [] yPos = {};
float [] dia = {};
float [] xSpeed = {};
float [] ySpeed = {};
Ball(){
}
Ball(float x, float y, float argDia){
xPos = append(xPos, x);
yPos = append(yPos, y);
dia = append(dia, argDia);
}
void bounce(){
for(int i=0; i<1; i++){
ellipse(xPos[i], yPos[i], 50, 50);
xPos[i] += xSpeed[i];
yPos[i] += ySpeed[i];
if(xPos[i]<0 || xPos[i]>=width){
xSpeed[i] = -xSpeed[i];
}
if(yPos[i]<0 || yPos[i]>=height){
ySpeed[i] = -ySpeed[i];
}
}
}
}

I believe the confusion comes from the fact that your class has two constructors:
an empty constructor (that takes no arguments): Ball()
a constructor with position and argDia (guessing diameter ?) arguments: Ball(float x, float y, float argDia)
In setup() you call the empty constructor:
ball1 = new Ball();
This means the five float arrays still have a length of 0, hence the out of bounds exception.
Even if you call the position + diameter version of the constructor, the xSpeed, ySpeed arrays will still have length 0.
You could fix this by initialising the two two arrays as well as using this version of the constructor:
Ball ball1;
void setup() {
size(500, 500);
//ball1 = new Ball();
ball1 = new Ball(250, 250, 50);
}
void draw() {
background(255);
ball1.bounce();
}
class Ball {
float [] xPos = {};
float [] yPos = {};
float [] dia = {};
float [] xSpeed = {};
float [] ySpeed = {};
Ball() {
}
Ball(float x, float y, float argDia) {
xPos = append(xPos, x);
yPos = append(yPos, y);
dia = append(dia, argDia);
xSpeed = append(xSpeed, random(-1, 1));
ySpeed = append(ySpeed, random(-1, 1));
}
void bounce() {
for (int i=0; i<1; i++) {
ellipse(xPos[i], yPos[i], 50, 50);
xPos[i] += xSpeed[i];
yPos[i] += ySpeed[i];
if (xPos[i]<0 || xPos[i]>=width) {
xSpeed[i] = -xSpeed[i];
}
if (yPos[i]<0 || yPos[i]>=height) {
ySpeed[i] = -ySpeed[i];
}
}
}
}
This will work, however there is still a bit of confusion: why use the arrays at all if you're only looping once for the first element ? It makes the arrays and for loop mostly redundant.
You might choose to keep if you plan to change the diameter over time (which in your code is hardcoded to 50), maybe positions and velocities and render a changing history of a ball.
If you don't, you could simply use float properties instead of arrays:
Ball ball1;
void setup() {
size(500, 500);
ball1 = new Ball();
}
void draw() {
background(255);
ball1.bounce();
}
class Ball {
float xPos;
float yPos;
float diameter = 50;
float xSpeed;
float ySpeed;
Ball() {
xPos = width / 2;
yPos = height / 2;
xSpeed = random(-1, 1);
ySpeed = random(-1, 1);
}
void bounce() {
ellipse(xPos, yPos, diameter, diameter);
xPos += xSpeed;
yPos += ySpeed;
if (xPos < 0 || xPos >= width) {
xSpeed = -xSpeed;
}
if (yPos < 0 || yPos >= height) {
ySpeed = -ySpeed;
}
}
}
This looks more similar to the Bounce Processing Example.
You can at a later stage make an array of Ball objects.
Additionally it's worth formatting code as it saves you time reading/scrolling through it and visually it's easier to scan the structure of the program (how each part fits in) and therefore makes it easier to debug/run mentally. It takes no effort as you can simply press Ctrl+T on Windows/Linux or CMD+T on OSX. On the long run this will pay off, especially as programs get longer and more complex as you spend more time reading code than writing code. It's a good habit to pickup early while learning to code. Have fun!

Related

How can i make the size of ellipse keeps the size after i released the mouse

what I need to do is:
As long as the mouse is still pressed, the shapes get smaller and smaller with each frame (already complete it)
When the mouse is released, the shapes keep their size.
When the mouse has clicked again, the „explosion“ is reset (i.e. all shapes that are still visible from the previous explosion vanish and the explosion starts again).
float gravity = .4;
int particle_each_time = 4;
ArrayList<Particle> particle= new ArrayList(); // ArrayList to manage to list of all particles
void setup() {
size(640, 480);
}
void draw() {
background(0);
for (int i = 0; i < particle_each_time; i++) {
particle.add(new Particle(mouseX, mouseY));
}
for (int i = 0; i < particle.size(); i++) {
Particle p = particle.get(i);
p.update(gravity);
p.draw();
}
}
//Next tab
class Particle {
float x; //X Position
float y; //Y Position
float velX; //velocity on X axis
float velY; //velocity on Y axis
float size; // Size of the particle
// float sizeFromMouse;
float lifespan; // duration of the particle
float col;//create fire type colours
Particle(float x, float y) {
this.velY = random(-10, 10);
this.velX = random(-10, 10);
this.x = x;
this.y = y;
this.size = 20;
lifespan = 220.0;
col = random(#DE8816);
}
void update(float gravity) {
this.x += velX; // direction of X axis
velY += gravity; // gravity affectiing the velocity on Y axis causing to fall
this.y += velY; //direction of Y axis
lifespan -= 1.0;
if (mousePressed ) {
size = size - 0.51;
}
if (size<0) {
size = 1;
}
}
boolean isDead() {
if (lifespan < 0.0) {
return true;
} else {
return false;
}
}
void draw() {
stroke(0, lifespan);
fill(#DE8816, lifespan);
ellipse(x, y, size, size);
}
}

object releases another smaller object?

Can anyone help me?
So, I'm supposed to have a ball that is moving horizontally, such that every time I press the mouse, a ball would get shoot vertically, then slows down due to friction. The vertical ball would stay in the old position but the player would reset.
How do I go about doing that without using classes?
Here my code so far:
boolean circleupdatetostop = true;
float x = 100;
float yshot = 880;
float speedshot = random(4,10);
float speedx = 6;
void setup() {
size(1280,960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(x,880,80);
if (x > width || x < 0 ) {
speedx = speedx * -1;
}
if (circleupdatetostop) {
x = x + speedx;
}
if (circleupdatetostop == false) {
float locationx = x;
stroke(0);
fill(255,0,255);
circle(locationx,yshot,30);
yshot = yshot - speedshot;
}
}
void mousePressed () {
circleupdatetostop = !circleupdatetostop;
}
I'm not entirely sure if this is what you meant, but you could achieve shooting multiple balls by using ArrayList as well as processing's PVector to better handle the x and y coordinate pairs. If you wanted to look at classes, see this post.
import java.util.*;
// Whether the ball is moving or not
boolean circleupdatetostop = true;
// Information about the main_ball
PVector position = new PVector(100, 880);
PVector speed = new PVector(6, 0);
float diameter = 80;
// Information about the sot balls
ArrayList<PVector> balls_loc = new ArrayList<PVector>();
ArrayList<PVector> balls_speed = new ArrayList<PVector>();
float diameter_shot = 30;
float friction = 0.994;
void setup() {
size(1280, 960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(position.x, position.y, diameter);
// Remember to consider the radius of the ball when bouncing off the edges
if (position.x + diameter/2 > width || position.x - diameter/2 < 0 ) {
speed.mult(-1);
}
if (circleupdatetostop) {
position.add(speed);
}
// Cycle through the list updating their speed and draw each ball
for (int i = 0; i<balls_loc.size(); i++) {
balls_speed.get(i).mult(friction+random(-0.05, 0.05));
balls_loc.get(i).add(balls_speed.get(i));
stroke(0);
fill(255, 0, 255);
circle(balls_loc.get(i).x, balls_loc.get(i).y, diameter_shot);
}
}
void mousePressed(){
// Add a new ball to be drawn
if(circleupdatetostop){
balls_loc.add(new PVector(position.x, position.y));
balls_speed.add(new PVector(0, random(-4, -10)));
}
circleupdatetostop = !circleupdatetostop;
}

Processing 3.0: Accelerating pong ball not correctly bouncing

I'm learning Processing and am making modified version of pong game in processing 3. I have 2 balls simultaneously instead of just 1.
Also, one ball accelerates while the other ball slows down as the program runs.
My accelerating ball is working fine, it bounces around and increases speed. But, my slowing down ball is not working correct. The slowing ball moves in a very small area and does not even go close to the borders to bounce off. Help would be appreciated. Thanks.`
float ballXPosition;
float ballYPosition;
float ballTwoXPos;
float ballTwoYPos;
float xDirection;
float ballTwoXDir;
float yDirection;
float ballTwoYDir;
float radius = 12;
float xSpeed;
float ySpeed;
float ballTwoXSpeed;
float ballTwoYSpeed;
float MAX_SPEED = 15;
float MIN_SPEED = 0.2;
void setup()
{
size(600,600);
stroke(3);
background(255,255,255);
ballXPosition = width/2 + random(60);
ballTwoXPos= width/2 + random(60);
ballYPosition = height/2 + random(60);
ballTwoYPos = height/2 + random(60);
xDirection = random(1,3);
ballTwoXDir = random(1,3);
yDirection = random(1,3);
ballTwoYDir = random(1,3);
xSpeed = MIN_SPEED;
ySpeed = MIN_SPEED;
ballTwoXSpeed = MAX_SPEED;
ballTwoYSpeed = MAX_SPEED;
}
void createAcceleratingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(255,0,0);
ellipse(xpos, ypos, xstretch, ystretch);
}
void createSlowingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(0,0,255);
ellipse(xpos, ypos, xstretch, ystretch);
}
boolean isSpeedMax(float speed)
{
return speed > MAX_SPEED;
}
boolean isSpeedMin(float speed)
{
return speed < MIN_SPEED;
}
boolean isBallAtXBorder(float xpos)
{
if(xpos < radius || xpos > width - radius)
return true;
else
return false;
}
boolean isBallAtYBorder(float ypos)
{
if(ypos < radius || ypos > height - radius)
return true;
else
return false;
}
void draw()
{
background(255);
ballXPosition = ballXPosition + (xDirection * xSpeed);
ballTwoXPos = ballTwoXPos + (ballTwoXDir * ballTwoXSpeed);
ballYPosition = ballYPosition + (yDirection * ySpeed);
ballTwoYPos = ballTwoYPos + (ballTwoYDir * ballTwoYSpeed);
if(!isSpeedMax(xSpeed))
xSpeed *= 1.005;
if(!isSpeedMax(ySpeed))
ySpeed *= 1.003;
if(!isSpeedMin(ballTwoXSpeed))
ballTwoXSpeed = ballTwoXSpeed / 1.005;
if(!isSpeedMin(ballTwoYSpeed))
ballTwoYSpeed = ballTwoYSpeed / 1.003;
if(isBallAtXBorder(ballXPosition))
xDirection *= -1;
if(isBallAtYBorder(ballYPosition))
yDirection *= -1;
if(isBallAtXBorder(ballTwoXDir))
ballTwoXDir *= -1;
if(isBallAtYBorder(ballTwoYDir))
ballTwoYDir *= -1;
createAcceleratingBall(ballXPosition, ballYPosition, 2*radius, 2*radius);
createSlowingBall(ballTwoXPos, ballTwoYPos, 2.5*radius, 2.5*radius);
}
I think you have the wrong variables being tested for the slowing ball in the isBallAtXBorder and isBallAtYBorder functions. You're testing ballTwoXDir and ballTwoYDir - should you not be testing ballTwoXPos and ballTwoYPos?

Processing: How can I make multiple elements in a for() loop move to one location then return?

I have a grid of ellipses generated by two for() loops. What I'd like to do is have all of these ellipses ease into mouseX and mouseY when mousePressed == true, otherwise return to their position in the grid. How can I go about this? I've started with this template, which doesn't work as I can't figure out how affect the position of the ellipses, but the easing is set up.
float x;
float y;
float easeIn = 0.01;
float easeOut = 0.08;
float targetX;
float targetY;
void setup() {
size(700, 700);
pixelDensity(2);
background(255);
noStroke();
}
void draw() {
fill(255, 255, 255, 80);
rect(0, 0, width, height);
for (int i = 50; i < width-50; i += 30) {
for (int j = 50; j < height-50; j += 30) {
fill(0, 0, 0);
ellipse(i, j, 5, 5);
if (mousePressed == true) {
// go to mouseX
targetX = mouseX;
// ease in
float dx = targetX - x;
if (abs(dx) > 1) {
x += dx * easeIn;
}
//go to mouseY
targetY = mouseY;
// ease in
float dy = targetY - y;
if (abs(dy) > 1) {
y += dy * easeIn;
}
} else {
// return to grid
targetX = i;
// ease out
float dx = targetX - x;
if (abs(dx) > 1) {
x += dx * easeOut;
}
// return to grid
targetY = j;
// ease out
float dy = targetY - y;
if (abs(dy) > 1) {
y += dy * easeOut;
}
}
}
}
}
Any help would be greatly appreciated. I'm not sure in which order to do things/which elements should be contained in the loop.
Thanks!
You're going to have to keep track of a few things for each dot: its "home" position, its current position,its speed, etc.
The easiest way to do this would be to create a class that encapsulates all of that information for a single dot. Then you'd just need an ArrayList of instances of the class, and iterate over them to update or draw them.
Here's an example:
ArrayList<Dot> dots = new ArrayList<Dot>();
void setup() {
size(700, 700);
background(255);
noStroke();
//create your Dots
for (int i = 50; i < width-50; i += 30) {
for (int j = 50; j < height-50; j += 30) {
dots.add(new Dot(i, j));
}
}
}
void draw() {
background(255);
//iterate over your Dots and move and draw each
for (Dot dot : dots) {
dot.stepAndRender();
}
}
class Dot {
//the point to return to when the mouse is not pressed
float homeX;
float homeY;
//current position
float currentX;
float currentY;
public Dot(float homeX, float homeY) {
this.homeX = homeX;
this.homeY = homeY;
currentX = homeX;
currentY = homeY;
}
void stepAndRender() {
if (mousePressed) {
//use a weighted average to chase the mouse
//you could use whatever logic you want here
currentX = (mouseX+currentX*99)/100;
currentY = (mouseY+currentY*99)/100;
} else {
//use a weighted average to return home
//you could use whatever logic you want here
currentX = (homeX+currentX*99)/100;
currentY = (homeY+currentY*99)/100;
}
//draw the ellipse
fill(0, 0, 0);
ellipse(currentX, currentY, 5, 5);
}
}
Note that I'm just using a weighted average to determine the position of each ellipse, but you could change that to whatever you want. You could give each ellipse a different speed, or use your easing logic, whatever. But the idea is the same: encapsulate everything you need into a class, and then put the logic for one dot into that class.
I'd recommend getting this working for a single dot first, and then moving up to getting it working with multiple dots. Then if you have another question you can post the code for just a single dot instead of a bunch. Good luck.

Use an object with this code? Processing

How can I use the code I have now with an object where I can store the number of times the ball bounces and the color (when i add random color) and speed. Any pointers or tips would be greatful. I am new to OOP and it can get confusing for me. Thanks in advance
float x;
float y;
float yspeed = 0;
float xspeed = 0;
float balldiameter = 10;
float ballradius = balldiameter/2;
void setup() {
size (400,400);
background (255);
fill (0);
ellipseMode(CENTER);
smooth();
noStroke();
x = random(400);
y = 0;
}
void draw() {
mouseChecks();
boundaryChecks();
ballFunctions();
keyFunctions();
}
void mouseChecks() {
if (mousePressed == true) {
x = mouseX;
y = mouseY;
yspeed = mouseY - pmouseY;
xspeed = mouseX - pmouseX;
}
}
void boundaryChecks() {
if (y >= height - ballradius) {
y = height - ballradius;
yspeed = -yspeed/1.15;
}
if (y <= ballradius) {
y = ballradius;
yspeed = -yspeed/1.35;
}
if (x >= width -ballradius) {
x = width -ballradius;
xspeed = -xspeed/1.10;
}
if (x <= ballradius) {
x = ballradius;
xspeed = -xspeed/1.10;
}
}
void ballFunctions() {
if (balldiameter < 2) {
balldiameter = 2;
}
if (balldiameter > 400) {
balldiameter = 400;
}
ballradius = balldiameter/2;
background(255); //should this be in here?
ellipse (x,y,balldiameter,balldiameter);
yspeed = yspeed += 1.63;
// xspeed = xspeed+=1.63;
y = y + yspeed;
x = x + xspeed;
}
void keyFunctions() {
if (keyPressed) {
if(keyCode == UP) {
balldiameter +=1;
}
if (keyCode == DOWN) {
balldiameter -=1;
}
}
}
you will probably want to do the following:
create a new file called Ball.pde
In that file write:
public class Ball {
public float x;
public float y;
public float yspeed;
public float xspeed;
public float diameter;
public float radius;
public Ball(float initial_x, float initial_y, float diam) {
this.x = initial_x;
this.y = initial_y;
this.xspeed = 0;
this.yspeed = 0;
this.diameter = diam;
this.radius = diam/2;
}
public void move() {
// movement stuff here
}
}
This will give you a very basic Ball class. You can now use this class in your main sketch file like so:
Ball my_ball = new Ball(50, 50, 10);
you can access the balls members using:
my_ball.xspeed;
my_ball.yspeed;
my_ball.anything_you_defined_in_ball;
This will allow you yo store all relevent variables for the ball within its own class. you can even create more than 1.
Ball my_ball1 = new Ball(50, 50, 10);
Ball my_ball2 = new Ball(20, 20, 5);
Just to note that in Proccesing you don't need to create a new file for that, the code can go either in the same file (very bad practice as pointed below) or in a new tab of the IDE. If you are using the Processing IDE you can choose "new tab" from the arrow menu in the right and it will create the file for you. It will have ".pde" extension.

Resources