Better collision detection

I have a pong-like game, where the paddle position is tied to mouse pointer position. If I move the mouse slowly, the ball bounces as expected. If I move the mouse quickly, however, the ball will likely pass through the paddle. Is there a known way to get better collision detection? Using java … I attempted to increase frameRate() in draw() from the default of 60 loops per second to something huge, but ultimately this did not solve the issue. To demonstrate the problem move the mouse quickly toward the ball… it will likely pass through the paddle.

Any suggestions would be greatly appreciated! Here is full code …

Puck myPuck;
Paddle myPaddle;
PVector radius;

void setup() {
  size(1000, 800);
  radius = new PVector(20, 20);

  //initialize puck object
  myPuck = new Puck(radius);
  myPaddle = new Paddle();
}

void draw() {
  background(0);
  smooth();
  frameRate(10000);
  myPuck.display();
  myPaddle.display();
  myPuck.move();
  myPuck.bounce(myPaddle.getW(), myPaddle.getH(), myPaddle.getSpeed());
  myPaddle.getSpeed();
}

class Paddle {

  PVector pos; // x and y position of paddle
  PVector paddleSpeed; // x and y speed of paddle

  float paddleHeight=20;   // height of paddle
  float paddleWidth=100;   // width of paddle

  Paddle() {
    pos = new PVector(width/2, height/2); //creates a new PVector object for position of paddle
    paddleSpeed = new PVector(0, 1); //creates a new PVector object for speed of paddle
  }

  void move() {     // Change the position of the paddle
    pos.x = mouseX;
    pos.y = mouseY;
  }

  void display() {   // Display the puck as a red circle
    fill(250, 0, 0);
    noStroke();
    rectMode(CENTER);
    rect(mouseX, mouseY, paddleWidth, paddleHeight); // draw rect with mouse at center top of paddle
  }

  float getW() {  // Return the width of the paddle
    return paddleWidth;
  } 

  float getH() {  // Return the height of the paddle
    return paddleHeight;
  }

  PVector getPos() {    // Return the position of the paddle
    return pos;
  }

  PVector getSpeed() {    // Return the speed of the paddle
    paddleSpeed.x = mouseX-pmouseX;
    paddleSpeed.y = mouseY-pmouseY;
    println(paddleSpeed.y);
    return paddleSpeed;
  }

  void setPos(PVector _pos) {   //Set the radius of the circle, the size can’t be smaller than 1
    pos = _pos;
  }

  float getX() {     // Return the x position of the paddle
    return pos.x;
  }

  float getY() {     //Return the y position of the paddle
    return pos.y;
  }

  void setX(float _x) {     //Set the x position of the paddle, keeps the paddle within the window
    pos.x = _x;
  }

  void setY(float _y) {     //Set the y position of the paddle, keeps the paddle within the window
    pos.y = _y;
  }
}

class Puck {

  PVector pos; // x and y position of puck
  PVector speed; // x and y speed of puck
  PVector radius;   // x and y radius of puck

  Puck(PVector _radius) {
    pos = new PVector(random(width*.1, width*.9), height*.1); //creates a new PVector object for position of puck
    speed = new PVector(.5, .5); //creates a new PVector object for speed of puck
    radius = new PVector(_radius.x, _radius.y);  // create a new PVector object x and y radius
    //fill(250);
  }

  void move() {     // Change the position of the puck by speed
    pos.x = pos.x + speed.x;
    pos.y = pos.y + speed.y;
  }

  void display() {   // Display the puck as a red circle
    fill(250, 0, 0);
    ellipse(pos.x, pos.y, radius.x, radius.y);
  }

  void bounce(float paddleWidth, float paddleHeight, PVector paddleSpeed) { // Bounce

    if (pos.x-radius.x < 0 || pos.x + radius.x > width) { // bounce of side walls
      speed.x = speed.x * -1;
    }
    if (pos.y-radius.y < 0 || pos.y + radius.y > height) { // bounce off top and bottom walls
      speed.y = speed.y * -1;
    }
    if (pos.y==mouseY-paddleHeight/2-radius.y/2) {  // if puck is at paddle height... 
      if (mouseX-.5*paddleWidth <= pos.x && pos.x <= mouseX+.5*paddleWidth) { // ... and puck is within paddle width
        speed.y = speed.y * (-1*(1+abs(paddleSpeed.x)));  // reverse puck direction
        println(speed.y);
      }
    }
    if (pos.y==mouseY+paddleHeight/2+radius.y/2) {  // if puck is at bottom of paddle... 
      if (mouseX-.5*paddleWidth <= pos.x && pos.x <= mouseX+.5*paddleWidth) { // ... and puck is within paddle width
        speed.y = speed.y * (-1*(1+abs(paddleSpeed.x)));  // reverse puck direction
      }
    }
  } // end of bounce ()

  PVector getR() {  // Return the radius of the circle
    return radius;
  } 

  PVector setR(PVector _radius) {  // Set the radius of the circle, the size can’t be smaller than 1
    radius = _radius;
    return radius;
  }


  PVector getPos() {    // Return the position of the puck
    return pos;
  }

  void setPos(PVector _pos) {   //Set the position of the circle
    pos = _pos;
    // Try assertion here?  If incoming size is < 1 ... error?
  }

  float getX() {     // Return the x position of the puck
    return pos.x;
  }

  float getY() {     //Return the y position of the puck
    return pos.y;
  }

  void setX(float _x) {     //Set the x position of the puck, keeps the puck within the window
    pos.x = _x;
  }

  void setY(float _y) {     //Set the y position of the puck, keeps the puck within the window
    pos.y = _y;
  }
}
1 Like

A pretty common solution for Collision detection with fast Objects is to trace their paths and check the resulting lines for collision. This approach may be a bit more complicated, but in case of fast moving objects it is pretty much the only solution, especially when the objects are very small.
Here’s a link to a related question :


It should suffice to get the previous position, the current position and then trace a line and see if it collides with the Paddle. Or the other way around, depending on which one moves faster. So not that much more complicated in this case. Or just to make sure also extend a line from the Paddle and check if the lines intersect.