1

I am trying to find a good way to handle ball/paddle collisions/reflections in Pong. I've tried the "naive" approach of just checking x and y coordinates against each other, figuring out where the ball hits on the paddle and how to change reflection, etc, but it seems so tedious to do it this way. I feel like I have to check collisions against the front of the paddle, then the sides, etc.

Is there a good, general way I can check for a collision between the ball and the paddle (be it sides, front, etc), ensure the ball doesn't pass through the paddle, determine where the ball touches the paddle in terms of tangency (if we don't allow the ball to move through the paddle), and determine reflection rules based on that point of tangency?

I've already looked into Corey's Detection Kit but it didn't seem to work for my purposes.

Consider the picture at the bottom of this post. Let's say the red ball is where the ball WANTS to appear based on the speed/frame-based update routine for the ball. Using some routine, it determines there is an intersection because either the sprites overlap or the path of travel overlays the paddle. But I really want to bring the ball back up to where it's actually touching the paddle at tangency. Is there a general way to do this?

https://i.stack.imgur.com/Xo99a.png

John Smith
  • 133
  • 3
  • The problem you are experiencing is called "tunneling", doing a google search on "tunneling collision" should bring up some related results like this one: http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Detection_and_Physics_FAQ – John McDonald Jan 26 '12 at 19:37

2 Answers2

3

General-purpose solutions are always harder to implement than specific, corner case solutions. That is a fact of life in engineering. And it is the nature of shortcuts: They're quick, and you don't get to do everything you would have on the longer route. If you can shortcut it, when it comes to games anyway, then do. Anyhow...

Look at the point of tangency in your drawing. Connect that line to the centre of the green circle.

Now what you find is that that line is of length R, where R is the radius of your ball. In other words, at that perp distance, the ball is tangent to the paddle. So we need to find some point on the incoming trajectory where a line extended directly (perpendicularly) toward the surface of the paddle is of length R. That will be the exact point where the centre of the ball will be, as it becomes tangent to the paddle.

  • T: the point of tangency, which you marked as a square;
  • I: the point where the trajectory line intersects the paddle surface line;
  • C: the centre of the green circle, that we need to find.
  • A: the last point in free space where the ball was before the collision (last update).

Tan(theta) = Opposite/Adjacent

Adjacent = TI, the line whose length you want to find, so that you know exactly the x value at which to place the centre of the ball such that it is tangent to the paddle. Opposite = TC = R, the radius of your ball. Theta = angle TIA, the angle made by the tangent point and the last valid position of the ball. You should be able to determine this easily enough, it's just the angle between the two lines. So,

TI = TC / Tan(TIA)

Now you have the x (TC) and the y (TI) offset relative to your point of intersection, that shows where the circle's centre should be for it to be tangent.

New Centre = Intersection + Offset

HTH.

Engineer
  • 29,455
  • 4
  • 72
  • 120
  • In this case I figure my polygons are simple enough to do some basic math. For instance, say I use a basic hitTest to see if they are intersecting in the first place. Is there a way to figure out, based on the direction the ball had been moving at the time of collision, the point of tangency with respect to the paddle?

    I'll update my original post. One moment.

    – John Smith Jan 26 '12 at 17:50
  • (Don't get me wrong -- I love Doom and appreciate your answer XD But I think this question is a bit simpler!) – John Smith Jan 26 '12 at 19:12
  • So would I have to do this for the three relevant sides of my paddle? – John Smith Jan 26 '12 at 19:16
  • Also, I am using x/y coords as opposed to vectors. Is that going to hurt me here? – John Smith Jan 26 '12 at 19:22
  • @JohnSmith, Indeed, sorry. Removed the comment about Doom, educational as it may have been. Clarified; please re-read now (I tend to do many edits in a row). – Engineer Jan 26 '12 at 19:25
  • @JohnSmith And again. Brain sluggish. Sorted now. – Engineer Jan 26 '12 at 19:30
  • @JohnSmith And again. – Engineer Jan 26 '12 at 19:31
  • @JohnSmith No, it's the same thing. Vector classes just wrap up the functionality you'd have to write externally, anyway. – Engineer Jan 26 '12 at 19:32
  • So I imagine I have to repeat the process for where I bump the ball up to depending on whether or not the center of the ball lies above/below/within the x=y lines overlaying the corners of the paddle? – John Smith Jan 26 '12 at 19:33
  • Yep that's exactly what you need to do, figured you'd gotten that bit when I read your Q. The good news is its much easier to do that when you know the paddles are moving on perfect x or y axes, than to have to do it using eg. this. This is what I was saying about shortcut solutions for specific games. – Engineer Jan 26 '12 at 19:34
  • Awesome, will definitely look all this over in detail. Thanks so much – John Smith Jan 26 '12 at 19:36
0

For a simple implementation of 'checking' whether collision has occured. You could use this algorithm.

private function enterFrameListener(event:Event)
{
    if(ball.hitTestObject(paddle))
    {
        //assuming ball comes and hits the paddle from top and 
        // x coordinate increases to the right and y to the down
        if( ball.y >= paddle.y ) // 
        {
           //paddle.y is assumed to be the toppest point on the paddle
           // if paddle.y is the center point, use 
           // paddle.y-paddle.height/2

           //okay since the ball has hit the paddle and is intersecting it
           // this is a situation we do not want. change the position of the ball to                
           //a position where you are sure there would not be a
           //collision with the paddle. ie at that point ball.hitTestObject(paddle)                
           //should return false

           ball.y = paddle.y - ball.height/2;
           //  here I am assuming the ball has                
           //its orgin at center point

           //now just write your code for reversing the ball movement direction
           //i'm assuming its like this
           yVel = -1* yVel;

This should work for Pong ball - paddle collision.

Happy coding

Vishnu
  • 1,877
  • 4
  • 17
  • 26