3
\$\begingroup\$

I'm currently trying to build a Breakout clone as a first step into game development. I'm using the following collision detection code (adapted from https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection). I have a rectangle and a circle, and the following C# code:

       Point circleDistance = new Point(Math.Abs(ball.collisionRect.Center.X - block.collisionRect.Center.X), Math.Abs(ball.collisionRect.Center.Y - block.collisionRect.Center.Y));

        if (circleDistance.X > (block.collisionRect.Width / 2 + ball.collisionRect.Width / 2)) { return false; }
        if (circleDistance.Y > (block.collisionRect.Height / 2 + ball.collisionRect.Height / 2)) { return false; }

        if (circleDistance.X <= (block.collisionRect.Width / 2)) { return true; }
        if (circleDistance.Y <= (block.collisionRect.Height / 2)) { return true; }

        float cornerDistance_sq = (circleDistance.X - block.collisionRect.Width / 2) ^ 2 + (circleDistance.Y - block.collisionRect.Height / 2) ^ 2;
        Console.WriteLine("Corner dist = " + cornerDistance_sq);
        return (cornerDistance_sq <= ((ball.collisionRect.Height / 2) ^ 2));

The ball moves automatically, and the rectangle is controlled using the keyboard.

When a collision occurs, I'm simply inverting the X and Y components of the ball's speed vector.

Occasionally, however, when the rectangle is moving and collides with the ball on its left or right edge, it gets 'caught', and overlaps by more than a few pixels. This results in several collisions in quick succession, and the ball 'jitters' until the rectangle is moved out of the way.

You can see the overlap at https://i.stack.imgur.com/DBgVR.jpg

I'm not sure why this occurs - if I add a boolean variable 'previousCollide' that is set on collide, then stop inverting the vector if this is set, then unset it once collisions have stopped occurring, then whilst there is still visible overlap the 'jitters' go away.

How can I prevent this?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The usual way to prevent this (as far as I understand) is to have a concept of "collide and move." This means that if two objects collide, "backtrack" them until they're just touching at the moment of collision.

In your case, you may need to redo your algorithm to calculate when two objects will collide (instead of waiting for it to happen after the fact). Or, if they do collide, reverse the position of the ball according to the opposite direction of its velocity until it's on top of the paddle, and then bounce it.

I don't know if that makes sense, but basically, you want to tell when they just start to collide and THEN bounce.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for this! I've just tried adding a condition on collision that subtracts the last speed increment from the position vector, and does so in a while loop until no collision occurs, then does the bounce. However I'm getting some weird behaviour where legitimate collisions are being 'ignored'... needs a bit of work :) \$\endgroup\$ Oct 9, 2011 at 18:56
  • \$\begingroup\$ @codinghands Okay, what about going back to your old code and simply moving the ball up above the paddle on the first collision? \$\endgroup\$
    – ashes999
    Oct 9, 2011 at 20:54
  • \$\begingroup\$ This worked, in conjunction with a bit of line / circle intersection code! Thanks. \$\endgroup\$ Oct 16, 2011 at 14:46

You must log in to answer this question.

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