2
\$\begingroup\$

I am making Pong... again. Anyway, the collision detection. In the past, I had gotten it working, but it used a bunch of globals, and other nasty things. This time, I am trying it where I have a Paddle, Ball, and CollisionManager class. Basically, the the paddle and ball have move functions, which moves as they would normally, including potentially invalid places.Then, the CollisionManager's sole function would check for and resolve and collisions. I hope to keep this structure.

That works fine for ball->top/bottom collisions, and in keeping the paddles in bounds. However, the ball->paddle collision, or its inverse, I am having trouble with it. This is because there are three situations that can happen, which I have badly illustrated in Paint:

enter image description here

The ball can hit the paddle as normal, it can hit the top or bottom of the paddles, and finally, the paddle can move into the ball. My question is, how to handle all these cases correctly. Note that this would be, more or less, how to determine when each case happens - how they are handled is not part of my question.

I had thought of a potential solution - essentially retracing, pixel by pixel, the steps of the ball, untill it no longer collides with a paddle. Then, determine the case and do things. However, this seems a bit buggy, with corner cases and such, and additionally, failed in determining when the paddle runs into the ball.

Any ideas how to do this correctly?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

If I understand correctly, your game has discrete movement steps, but you need to calculate when and where two moving objects could collide?

Just simplify the problem by finding the relative motion of the ball to the paddle. Then it's just a matter of figuring out which set of static edges (the paddle edges) collide with the moving ball. I assume you know how to handle corner (literally) cases?

For example, if the ball's motion vector is [ball_i, ball_j] and the paddle's motion vector is [paddle_i, paddle_j], get the relative motion vector (with respect to the paddle) by subtracting the paddle's motion vector from all other motion vectors. So given this:

enter image description here

Subtracting the paddle's motion vector from all motion vectors, you get this:

enter image description here

Note: subtracting the paddle's motion vector from itself makes the paddle stationary!

Then it's simply a problem of whether the motion of the ball, starting from its initial position and moving in the direction of [ball_i - paddle_i, ball_j - paddle_j], collides with which sides of the paddle.

\$\endgroup\$
3
  • \$\begingroup\$ I can calculate if they collide, but I was asking for a way to do it when you use the principle "move, then check". That being said, this looks like it could be useful if I were doing it that way, with vectors, but looks similar to pixel-by-pixel movement and checking, which was not what I was aiming for in this case. \$\endgroup\$ Mar 27, 2013 at 2:56
  • \$\begingroup\$ @Pawnguy7 This answer more or less covers your question of "paddle moving into ball", and it is not the same as a pixel-by-pixel movement checking, as the movement intervals can be of any magnitude. \$\endgroup\$ Mar 27, 2013 at 3:22
  • \$\begingroup\$ @Pawnguy7 it's easy to check line-line (movement to paddle side) intersection compared to iterating pixel by pixel \$\endgroup\$ Mar 31, 2013 at 0:38
0
\$\begingroup\$

Are you doing this in C++? I made a "break out" style game in java and had to solve this problem. I don't know if C++ has this (I'm sure it does) but there is a Rectangle class in the basic geometry library that has an "intersects" method. You pass a rectangle argument to it and it checks if the two rectangles intersect. Your collision check would look something like: if(paddle1.intersects(ball)) {collide();}

If you can't find a method like that, it's pretty easy to make your own. I ended up making my paddle out of four rectangles, one for each side of the paddle so I could easily determine which side of the paddle was struck, and therefore, how to deflect the ball.

If this sounds at all helpful, I can elaborate more.

\$\endgroup\$
6
  • \$\begingroup\$ C++ has no (built-in) geometry library, but it's trivial to make your own, especially since C++ supports operator overloading. I'm curious about how you dealt with situations where the ball collides with two sides at once (a corner). \$\endgroup\$
    – Apples
    Mar 27, 2013 at 2:44
  • \$\begingroup\$ The above, and the library I am using (third-party) has it. My problem is not this, though, is how to determine how they collide. Knowing the paddle collides with the ball could be any of three cases, and each is handled differently. \$\endgroup\$ Mar 27, 2013 at 2:54
  • \$\begingroup\$ I guess I'd need to know more about how your main loop works. Could you post a snippet of the movement and collision check code? \$\endgroup\$
    – Alcanteria
    Mar 27, 2013 at 16:52
  • \$\begingroup\$ I dealt with multiple collisions in a simple way. All my checks were done in loops, so every frame the ball would loop through each active brick to check for a collision. When it made contact it would go through another loop to see which side it hit. As soon as a side was found to make contact, I set the velocity of the ball accordingly, and broke out of the loop, eliminating double hits. This would give a priority of collisions to a certain side, but it wasn't noticeable. \$\endgroup\$
    – Alcanteria
    Mar 27, 2013 at 16:57
  • \$\begingroup\$ How did you find out which side the ball hit? \$\endgroup\$ Mar 27, 2013 at 17:08
0
\$\begingroup\$

first you can simplify the collision check by imagining the ball as a single point (its center) moving about
and the rectangle as a larger rounded rectangle (with the radius of the corners equal to the radius of the ball and the center points of the corners the corners of the original rectangle),

then you can use CongXu's answer and just check the intersections of a line (the path of the ball) with another (axis-aligned) line or a circle segment and depending on which segment collides you know where the collision point is and change the behavior

on the off chance that you have 2 collisions just take the one closer to the start point

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .