Collision Between Ball and Paddle for Pong type game

edited January 2016 in How To...

Hello,

I am relatively new to processing, having only started learning it this year as part of my course at university. I am writing a small game for part of my project but am having trouble working out how to get collision between to class-objects. I need to detect when the ball has hit the paddle. I can do the points and reversing of direction myself, but I really am struggling with the collision.

Here is my code: Void setup and draw functions

int P1points = 0;
int P2points = 0;

Ball myBall;
P1Paddle myPaddle;
P2Paddle yourPaddle;

void setup() {
  size(1280, 720);
  background(0);

  myBall = new Ball(320, 500);
  myPaddle = new P1Paddle(1260,308);
  yourPaddle = new P2Paddle(20,308);
}
void draw() {
  background(0);
  smooth();
  textSize(32);
  text("P1 Points: " + P1points, 10, 40);
  text("P2 Points: " + P2points, 10, 80);
  stroke(255);
  line(0, 90, 1280, 90);
  line(0, 95, 1280, 95);
  line(0, 710, 1280, 710);
  line(0, 715, 1280, 715);
  myBall.display();
  myPaddle.display();
  if (key == ENTER) {
    myBall.run();
  }
  myPaddle.run();
  yourPaddle.run();

}

  class P1Paddle {
  //GLOBAL VARIABLES
  float x = 0;
  float y = 0;
  float xspeed = 3;
  float yspeed = 3;
  int pad2w = 10;
  int pad2h = 80;

  //CONSTRUCTOR
  P1Paddle(float _x, float _y) {
    x = _x;
    y = _y;
  }
  //FUNCTIONS
  void run() {
    display();
    move();
  }
  void move() {
    if (key == CODED) {
      if (keyCode == UP) {
        if (keyPressed) {
          y = y - 4;
        }
        if (y <=145) {
          y = 145;
        }
      }
      if (keyCode == DOWN) {
        if (keyPressed) {
          y = y + 4;
        }
        if (y >= 660) {
          y = 660;
        }
      }
    }
  }

  void display() {
    rectMode(CENTER);
    rect(x, y, pad2w, pad2h);
  }
}

  class P2Paddle {
  //GLOBAL VARIABLES
  float x = 0;
  float y;
  float xspeed = 3;
  float yspeed = 3;
  int padw = 10;
  int padh = 80;

  //CONSTRUCTOR
  P2Paddle(float _x, float _y) {
    x = _x;
    y = _y;
  }
  //FUNCTIONS
  void run() {
    display();
    move();
  }
  void move() {
    if (keyPressed) {
      if (key == 'W' || key == 'w') {
        y = y - 4;
      }
      if (y <=145) {
        y = 145;
      }
      if (key == 'S' || key == 's') {
        y = y + 4;
      }
      if (y >= 660) {
        y = 660;
      }
    }
  }

  void display() {
    rectMode(CENTER);
    rect(x, y, padw, padh);
  }
}


  class Ball {
  //GLOBAL VARIABLES
  float x = 0;
  float y = 0;
  float xspeed = 3;
  float yspeed = 3;
  int ew = 15;
  int eh = 15;

  //CONSTRUCTOR
  Ball(float _x, float _y) {
    x = _x;
    y = _y;
  }
  //FUNCTIONS
  void run() {
    display();
    move();
    bounceY();
    addpoints();
  }
  void move() {
    x += xspeed;
    y += yspeed;
  }
  void display() {
    ellipse(x, y, ew, eh);
  }
  void bounceY() {
    if (y <= 95) {
      yspeed = yspeed * -1;
    }
    if (y >= 710) {
      yspeed = yspeed * -1;
    }
  }
  void addpoints() {
    if (x >= 1250) {
      P1points = P1points +1;
    }
    if (x <= 18) {
      P2points = P2points +1;
    }
  }
}

Any help would be greatly appreciated..Oh and the other problem I have to is that when I press enter the ball will move, but trying to move the paddles at the same time results in the ball pausing...Though I am trying to work all this out.

Tagged:

Answers

  • edited January 2016

    First a little note, you have separate classes for P1 and P2 paddles, which is not actually a good practice. It is better to have a paddle as one class and either pass to constructor which player it is and conditionally select how to control it, or you can create a Paddle class and extend it with P1 and P2 classes. But nevermind, if it works, that's fine.

    Colission detection for ball and 1st paddle will look like this:

    void bounceX(){
        if (x>myPaddle.x && y>myPaddle.y && y< myPaddle.y+myPaddle.pad2h){
        xspeed *= -1;
        }
    }
    

    I'm sure you can do the same for second one. BTW, some of your variables also confusing, there's no need to call variable pad2h, you can use same padh, as it is in different classes and it is strange to have something that is 2 in class that says that it is player one.

  • edited January 2016

    I also want to show you how this function may look like, if you had one class for both paddles:

    void bounceX(Paddle p){
        if (x>p.x && y>p.y && y< p.y+p.padh){
        xspeed *= -1;
        }
    }
    

    So now, to check the collision between both paddles, you don't need to write additional conditionals, you can just say in run function:

    bounceX(myPaddle);
    bounceX(yourPaddle);
    

    This is easier and is more object-oriented.

  • edited January 2016

    About your problem with not moving ball. Have in the ball class boolean isRunning = false;, change run to:

     void run() {
        if (isRunning){
          display();
          move();
          bounceY();
          addpoints();
        }
      }
    

    And instead lines 29-31 put some code in keyPressed():

    void keyPressed(){
    if (key == ENTER) {
        myBall.isRunning = true;
      }
    }
    
  • Wow! I really appreciate all the help! I managed to add a lot more stuff to my code and it runs really well now thank you! :)

  • I actually have done way more as I've said but now I'm stuck on yet another part...I'm trying to set the limit for the speed of the ball (you can only react so fast) and I just can't get it... this is what I have set so far.

    class Ball {
      //GLOBAL VARIABLES
      boolean isRunning = false;
      float bx = 0;
      float by = 0;
      float xspeed = 3;
      float yspeed = 3;
      int ew = 15;
      int eh = 15;
    
      //CONSTRUCTOR
      Ball(float _x, float _y) {
        bx = _x;
        by = _y;
      }
    
      //FUNCTIONS
      void run() {
        if (isRunning) {
          display();
          move();
          bounceX1();
          bounceX2();
          bounceY();
        }
      }
      void updatepos() {
        bx = 640;
        by = 403;
        if (P1points > P2points) {
          xspeed = -xspeed;
          yspeed = -yspeed;
        } else if (P2points < P1points) {
          xspeed = +xspeed;
          yspeed = +yspeed;
        }
      }
      void move() {
        bx += xspeed;
        by += yspeed;
      }
      void display() {
        if (P1points >= 7 || P2points >= 7) {
          fill(random(0, 255), random(0, 255), random(0, 255));
        } else {
          fill(255);
        }
        ellipse(bx, by, ew, eh);
      }
      void bounceX1() {
        if (bx > myPaddle.x - ew && by > myPaddle.y && by < myPaddle.y+myPaddle.padh) {
          if(xspeed >= 5 || xspeed <= -5){
          xspeed = xspeed * 1;
          }
          if (xspeed < 5 || xspeed > -5) {
            xspeed = xspeed * -1.25;
          }
          paddle1.trigger();
          if(myPaddle.yspeed < 5 || myPaddle.yspeed >-5){
          myPaddle.yspeed = myPaddle.yspeed * 1.15;
          }
          if (myPaddle.yspeed >= 5 || myPaddle.yspeed <= -5) {
            myPaddle.yspeed = myPaddle.yspeed *1;
          }
          if (myPaddle.yspeed < 5 || myPaddle.yspeed >-5){
          yourPaddle.yspeed = yourPaddle.yspeed * 1.15;
          }
          if (yourPaddle.yspeed >= 5 || myPaddle.yspeed <= -5) {
            yourPaddle.yspeed = yourPaddle.yspeed *1;
          }
        }
      }
      void bounceX2() {
        if (bx < yourPaddle.x + ew && by > yourPaddle.y && by <= yourPaddle.y + yourPaddle.pad2h) {
          if (xspeed >= 5 || xspeed <= -5) {
            xspeed = xspeed * 1; 
          }
          if (xspeed < 5 || xspeed > -5){
          xspeed = xspeed * -1.25;
          }
          paddle1.trigger();
          if (myPaddle.yspeed < 5 || myPaddle.yspeed > -5){
          myPaddle.yspeed = myPaddle.yspeed * 1.15;
          }
          if (myPaddle.yspeed >= 5 || myPaddle.yspeed <= -5) {
            myPaddle.yspeed = myPaddle.yspeed *1;
          }
          yourPaddle.yspeed = yourPaddle.yspeed * 1.15;
          if (yourPaddle.yspeed >= 5) {
            yourPaddle.yspeed = yourPaddle.yspeed *1;
          }
        }
      }
        void bounceY() {
          if (by <= 95 + eh) {
            yspeed = yspeed * -1;
            ball.trigger();
          }
          if (by >= 710 - eh) {
            yspeed = yspeed * -1;
            ball.trigger();
          }
        }
      }
    
  • Limiting any variable is easy with the use of constrain()

  • I tried using it but for some reason it still won't limit the speed. It just keeps getting faster and faster until the ball just passes through.

  • Nevermind! Fixed it. :)

Sign In or Register to comment.