mike
mike

Reputation: 110

Ball passing through paddle in Pong game

I'm making another Pong clone using HTML5 canvas and JavaScript. The problem I'm having can best be described in this diagram:

https://i.sstatic.net/fPIOH.png

If the ball is moving at 10px per frame, I can't just test if the ball is touching the paddle, as it is possible that the ball has surpassed the paddle in that frame-step.

Is there any way to test if the ball has collided with the paddle?

Edit: The only 2 solutions I can think of at the moment are:

Test at every position

or

Make a collision area 10px behind the paddle

Upvotes: 4

Views: 1641

Answers (4)

rcravens
rcravens

Reputation: 8390

you can detect collisions by determining if the line defined by the paddle and the incremental transit line intersect. If they do, then you can apply the bounce logic at the intersection point.

Hope that helps.

Bob

Take a look here:

http://mathcentral.uregina.ca/QQ/database/QQ.09.97/parsons1.html

Remember you geometry is simpler because you have a vertical line as the paddle. Here is the simplification (check my math here):

// line 1 (x1,y1) to (x2,y2)
var x1 = -1.0;
var y1 = 1.0;
var x2 = 1.0;
var y2 = -1.0;
// line 2 (x3,y3) to (x4,y4)
// note: this is the paddle and y3=y4
var x3 = -1.0;
var y3 = 0.5;
var x4 = 1.0;
var y4 = 0.5;

​var ix, iy;
function calculateIntersection(){
  var ixtop = x1*(y2-y3) + x2*(y3-y1);
  var ixbot = y2 - y1;
  var ix = ixtop/ixbot;

  var iy = y3;
}​

I believe this is the most efficient approach and will provide an accurate answer. Moving diagonally through the pixel matrix will result in artifacts if you don't have sufficient resolution.

Upvotes: 3

nonopolarity
nonopolarity

Reputation: 151036

I assume you either have a dx and dy which is the delta of the ball coordinate per movement, or an angle (say θ = theta), so in this case dx is 10 * cos(th) and dy is 10 * sin(th).

You just need to see, whether x + dx is past the paddle's x-coordinate, say 600, and if so, for simplicity, say it takes 2/3 of dx to reach there, so you can use y + dy * (2/3) to find out the y where the ball will end up, when the ball reach the x-coordinate of the paddle.

If that y is less than the paddle's top edge (the top y), or greater than the paddle bottom edge (the bottom y), then it is a miss. Otherwise, it is a hit.

Upvotes: 1

Ivo Wetzel
Ivo Wetzel

Reputation: 46745

Complicated solution, vector stuff.

Simple solution, instead if moving the ball by simply adding 10px, move it by 1px 10 times and check each time whether it collides:

for(var i = 0; i < 10; i++) {
   moveBallByOne();
   if (ballCollision()) { // you could check for a simple bounding box overlap here
       invertBallDirection();
       break;
   }
}

Upvotes: 2

Chris Laplante
Chris Laplante

Reputation: 29658

Every time your ball hops ten pixels, you have to calculate each position in between to make sure it isn't trying to pass through a solid object, as you have seen will happen.

Upvotes: 1

Related Questions