Search code examples
c#xnacollision-detectiongame-physics

How to improve/fix collision detection between ball and paddle?


Basically i am in the process of making a game which is like pong, breakout, etc. I am having some problems when the ball and paddle collide... but only sometimes!

This video here is what is occuring: http://www.youtube.com/watch?v=uFZIxFIg0rI

So yea, basically the ball sometimes seems to go a bit crazy when it collides with the paddle... normally if i am moving the paddle in the opposite direction of which the ball is approaching it. Also the ball sometimes get's caught between the bottom of the game window and the paddle... even though i have code to stop the ball, paddle, etc from going outside of the screen...

Any ideas... or simple fixes? Thanks

Oh btw... here is the code i am using for collision detection between the ball and paddle and to stop them from going outside of the game window:

//CODE FOR CHECKING IF THE BALL IS OUTSIDE OF THE SCREEN

        //checks for collision with left wall
        if (pPosition.X <= 0)
        {
            pVelocity.X = -pVelocity.X;                
        }

        //checks for collision with right wall
        if (pPosition.X + pTexture.Width >= screenWidth)
        {
            pVelocity.X = -pVelocity.X;                                           
        }

        //checks for collision with top wall
        if (pPosition.Y <= 0)
        {
            pVelocity.Y = -pVelocity.Y;                
        }

        //checks for collision with bottom wall
        if (pPosition.Y + pTexture.Height >= ScreenHeight)
        {
            pVelocity.Y = -pVelocity.Y; //only need to invert Y velocity...                    
        }
    }


//CODE FOR CHECKING COLLISION BETWEEN BALL AND PADDLE

if (Ball.pRectangle.Intersects(Paddle.GetRectangle))
        {
            //Ball.pPosition.Y -= Ball.pVelocity.Y;
            Ball.pVelocity.Y = -Ball.pVelocity.Y;
        }            

        Ball.pPosition += Ball.pVelocity; //As this is in the update method, this just enables the ball to keep moving each frame...

EDIT at 17:21:

if (Ball.pRectangle.Intersects(Paddle.GetRectangle))
        {
            if (Ball.pRectangle.Bottom > Paddle.GetRectangle.Top)
            { //intersecting top of paddle
                //WORKING
                Ball.pPosition.Y = Paddle.GetRectangle.Top - Ball.pHeight;
                Ball.pVelocity.Y = -Ball.pVelocity.Y;
            }


 if (Ball.pRectangle.Right > Paddle.GetRectangle.Left && Ball.pRectangle.Right <     Paddle.GetRectangle.Right)
            { //intersecting left of paddle
                //WORKING
                Ball.pPosition.X = Paddle.GetRectangle.Left - Ball.pWidth;
                Ball.pVelocity.X = -Ball.pVelocity.X;
            }

 if (Ball.pRectangle.Left < Paddle.GetRectangle.Right && Ball.pRectangle.Left > Paddle.GetRectangle.Left)
            { //intersecting right of paddle
                //NOT WORKING
                Ball.pPosition.X = Paddle.GetRectangle.Right + Ball.pWidth;
                Ball.pVelocity.X = -Ball.pVelocity.X;
            }
        }

Solution

  • Your problem is not that the ball gets caught between the bottom of the game window and the paddle, but it gets stuck within the paddle.

    Avoid that by setting the Y coordinate of the ball to be above the paddle when you detect a hit with the paddle from the top.

    If you detect a hit on the bottom of the paddle, then you have to set the Y coordinate of the ball to be below the paddle.

    In the same way if you have hit from the side you have to set the X coordinate of the ball, so that it is outside of the paddle.

    The point is that after the hit the panel and the ball must not touch each other, otherwise you detect a second hit immediately.