Pong - problems with boundary check

Hi,

I’m new to processing and working on implementing a simple pong like program. At this point I have created a Ball and a Paddle. The Paddle is simply a rectangle that tracks the mouseX variable.

Now I am working on the ball. Eventually I will want it to bounce off the paddle at an angle. But before that I am just trying to get the ball to bounce off the screen boundaries. Later I will handle the case where the paddle misses the ball or bounces off the paddle.

So for now basically I just want my ball to bounce at an angle off the four walls (screen boundaries).

This is my code so far:
Ball ball;
Paddle paddle;


void setup() {
  size(640, 480);
  paddle = new Paddle();
  ball = new Ball(paddle);
}

void draw() {
  background(0);
  paddle.draw();
  paddle.move();
  
  
  
  ball.checkBoundaries();
  paddle.checkBoundaries();
  
  ball.draw();
  ball.move();
}

class Ball {
  float xPos;
  float yPos;
  
  float xSpeed = 2.8;
  float ySpeed = 2.2;
  
  int xDirection = 1;
  int yDirection = 1;
  
  int rad = 16;
  
  final float speed = 5;
  
  Paddle paddle;
  
  public Ball(Paddle paddle){
    paddle = paddle;
    
    // set starting position of the ball, start in center of screen
    xPos = width / 2;
    yPos = height / 2;
  }
  
  
  public void move() {
    // update the ball's position
    xPos += (xSpeed) + (xSpeed * xDirection);
   // yPos += (ySpeed) + (ySpeed * yDirection);
 
  }
  
  public void draw() {
    ellipse(xPos, yPos, rad, rad);
    checkBoundaries();
  }
  
  public void checkBoundaries() {
    if(xPos > width - rad || xPos < rad) {
      xDirection *= -1;
    }
    
    if(yPos > height - rad || yPos < rad) {
     yDirection *= -1;
     println("yDirection: " + yDirection + "yPos: " + yPos);
    }
  }
  
  public void checkCollision() {
    
  }
}

And finally my Paddle:

class Paddle {
  float x;
  final float y = 440;
  
  float speedX;
  
  public Paddle() {
    
  }
  
  public void move() {
    x = mouseX;
  }
  
  public void draw() {
    fill(255);
    rect(x, y, 100, 20);
  }
  
  public void checkBoundaries(){
    if(x < 0){
      x = 0;
    }
    
    if(x > (width - 100)){
     x = width - 100; 
    }
  }
}

I don’t understand why the ball is simply falling diagonally to the right and then disappearing off the screen instead of bouncing back at an angle.

Any help would be much appreciated.

Thanks,
Marc

1 Like
class Ball {
  float xPos;
  float yPos;
  
  float xSpeed = 2.8;
  float ySpeed = 2.2;
  
  int xDirection = 1;
  int yDirection = 1;
  
  int rad = 16;
  
  final float speed = 5;
  
  Paddle paddle;
  
  public Ball(Paddle paddle){
    paddle = paddle;
    
    // set starting position of the ball, start in center of screen
    xPos = width / 2;
    yPos = height / 2;
  }
  
  
  public void move() {
    // update the ball's position
    //xPos += (xSpeed) + (xSpeed * xDirection);
    yPos += (ySpeed) + (ySpeed * yDirection);
 
  }
  
  public void draw() {
    ellipse(xPos, yPos, rad, rad);
    checkBoundaries();
  }
  
  public void checkBoundaries() {
    if(xPos > width - rad ) {
      xSpeed -= 2.2;
    }
    if(xPos <rad ) {
      xSpeed = 2.2;
    }
    
    if(yPos > height) {
     ySpeed = -2.2*yDirection;
     println("yDirection: " + yDirection + "yPos: " + yPos);
    }
    if(yPos<rad) {
     ySpeed = 2.2*yDirection;
     println("yDirection: " + yDirection + "yPos: " + yPos);
    }
  }
  
  public void checkCollision() {
    
  }
}

looks suspicious

Why not

+= (xSpeed * xDirection);

not sure why but that approach doesnt work in my sketch.
:confused:

also the double checkBoundaries(); was confusing it.

Use this in the ball class

  public void draw() {
    ellipse(xPos, yPos, 
      rad, rad);
    // checkBoundaries();
  }

I always advice to check the boundaries separately because the *-1
can lead to stuttering (and lead to the problem with the double call to checkBoundaries() imho)

abs() gives always the positive value (e.g. 2.8 without the minus - sign); with *-1 this gives always a negative value. So no stuttering can occur.


  public void checkBoundaries() {
    if (xPos > width - rad) {
      xSpeed = abs(xSpeed) * -1;
    }

    if ( xPos < rad ) {
      xSpeed = abs(xSpeed);
    }

    if (yPos > height - rad) {
      ySpeed = abs(ySpeed) * -1;
      println("yDirection: " + yDirection + "yPos: " + yPos);
    }
    if ( yPos < rad ) {
      ySpeed = abs(ySpeed);
    }
  }
1 Like

Wow! Thank you for your quick reply and detailed help. I really appreciate it. Now I have the ball bouncing off the edges of the screen.

Yeah, those extra calls to checkBoundaries were redundant.

I am not sure I understand how using abs() avoids stuttering - can you elaborate on that a bit.

Once I get that I will move on to adding logic to detect collisions between the ball and the paddle and have the ball bounce off the paddle. My paddle is 100 pixels wide. So if the x position of the ball - radius is equal to any point between the x position of the paddle and the x position of the paddle + 100 the ball would bounce off of it.

Does this make sense? I will try writing the code for that.

I am thinking that if, for example I want the player to have 5 lives I can use a counter. I’d decrement the counter each time a ball drops off the screen and then start off with a new ball.

However one problem I can think of in advance is that when balls drop off the screen they don’t really disappear - there is still a ball taking up memory and moving through coordinates that are off screen, right? So how do I destroy a ball after it falls off the screen? Would I be better off using an arraylist and removing the ball from it each time it drops off screen?

Thanks again for your time and help.
Marc

1 Like

You are on a good track

No need for an arraylist just re-init the ball with a new random position and speed

I have added this to checkBoundaries to check for collisions between the ball and paddle: (100 is the length of the paddle, I’ll move that to a constant later )

for(float index = paddle.x; index < paddle.x + 100; index++) {
      if(xPos == index) {
       ySpeed = abs(ySpeed) * -1;
      }
    }

But I am getting null pointer exception. Where did I go astray here?

Does processing have a simpler way to check collisions?

Thanks,
Marc

That’s not correct

First kill the boundary check for the lower screen border

Instead just put

if(ball.x>=paddle.x&& ball.x<paddle.x plus paddle width && ball.y > paddle.y)

bounce

Pseudo-code

Thank you!

I am having a problem accessing paddle.x.

In my main program I create a paddle and then I create a ball, passing to it the paddle.

I can access paddle.x fine in the main program and in my Ball constructor. But when I try to access it elsewhere in my Ball class it throws null pointer exception.

Here is my current code:

Ball ball;
Paddle paddle;


void setup() {
  size(640, 480);
  paddle = new Paddle();
  ball = new Ball(paddle);
 // println(paddle.x); prints paddle.x
}

void draw() {
  background(0);
  paddle.draw();
  paddle.move();
  
  paddle.checkBoundaries();
  
  ball.draw();
  ball.move();
}

class Paddle {
  public float x;
  public final float y = 440;
  
  float speedX;
  
  public Paddle() {
    x = 0;
    
  }
  
  public void move() {
    x = mouseX;
  }
  
  public void draw() {
    fill(255);
    rect(x, y, 100, 20);
  }
  
  public void checkBoundaries(){
    if(x < 0){
      x = 0;
    }
    
    if(x > (width - 100)){
     x = width - 100; 
    }
  }
}

class Ball {
  float xPos =0;
  float yPos = 0;
  
  float xSpeed = 2.8;
  float ySpeed = 2.2;
  
  int xDirection = 1;
  int yDirection = 1;
  
  int rad = 16;
  
  final float speed = 5;
  
  Paddle paddle;
  
  public Ball(Paddle paddle){
    paddle = paddle;
    
    // set starting position of the ball, start in center of screen
    xPos = width / 2;
    yPos = height / 2;
   // println(paddle.x); prints paddle.x
    
  }
  
  
  public void move() {
    // update the ball's position
    xPos +=  (xSpeed * xDirection);
    yPos +=  (ySpeed * yDirection);
    // println(paddle.x); throws null pointer exception
 
  }
  
  public void draw() {
    ellipse(xPos, yPos, rad, rad);
    checkBoundaries();
  }
  
  public void checkBoundaries() {
    //// check collision between ball and paddle, 100 = paddle length
    //if(xPos > paddle.x){
    ////if(xPos > paddle.x && xPos < (paddle.x + 100) && (yPos + 20) >= paddle.y) {
    //  xSpeed = abs(xSpeed) * -1; 
    //  ySpeed = abs(ySpeed) * -1; 
    //}
    println(paddle.x);
    
     
    
    if(xPos > width - rad) {
     xSpeed = abs(xSpeed) * -1; 
    }
    
    if(xPos < rad) {
     xSpeed = abs(xSpeed); 
    }
    
    if(yPos > height - rad) {
     ySpeed = abs(ySpeed) * -1; 
    }
    
    // check lower screen boundary
    //if(yPos < rad) {
    // ySpeed = abs(ySpeed); 
    //}
  }
  
  public void checkCollision() {
    
  }
}

Paddle and Ball are included together above.

So I am confused about passing objects in processing. I had to use globals to make this work. Instead - as above - what I really want to do is have the ball know about the paddle. But after passing to the constructor when I try to access paddle.x I get null pointer.

Note: I am using all public and no getter/setters for simplicities sake.

That’s wrong when you have it in the ball class

You want the ball class to check against the normal paddle that was declared before setup