Search code examples
c++collisionsfmlpong

Ball passing through paddle from certain angles


I'm creating a pong clone for school with C++ and SFML 2.1 and I'm having a little problem when the ball hits the left paddle at sharp angles (It goes through).

The right paddle works fine at all angles, and as far as i can remember they're using the same code.

This is the code I'm using for collision:

    for (auto& it : collisionPaddles)
    {
        if (this->ballShape.getGlobalBounds().intersects(it->getGlobalPaddleBounds()))
        {
            float deltaDistance = (this->y + this->radius) - (it->y + it->height / 2);
            bool fromLeft = true;

            if ((ballAngle < (3*myMath::MY_PI/2) && ballAngle > myMath::MY_PI/2))
            {
                fromLeft = false;
            }
            else
            {
                fromLeft = true;
            }

            ballAngle = static_cast<float>(deltaDistance * (myMath::MY_PI/180));

            if (fromLeft)
            {
                ballAngle = static_cast<float>(myMath::MY_PI - ballAngle);
            }
            moveBall(2);
        }
    }

Solution

  • That's not the way a good pong should be implemented. When your model of physics uses some deltas, you get a lot of artefacts. The one of most prominent is objects passing through each other. In such simple cases deltas should be used for animation only.

    Here's the way I would solve it. When the ball gets its initial speed and vector of movement, I would calculate the whole path until it hits the player's baseline.

    1. Calculate an initial ray from the current position of the ball, directed the same way it moves.
    2. Intersect that ray with segments that consistute the borders of your field.
    3. Calculate the time that is needed to reach that intersection point.
    4. Calculate the new ray from the intersection point towards the new movement vector.
    5. Repeat steps 2-4 until you hit a player's base line. Sum all the times.

    Now you have a relative time of the hit with baseline and the place it will happen. Now on every frame you should

    1. Check if that collision time has been between the previous frame and the current one. If it was,
    2. Calculate the expected position of paddle at that moment.
    3. If the segment of paddle contains that intersection point, it was reflected. Calculate the new path as described before.

    This way you'll get true game mechanics that are not limited by most of the aspects of game development, i.e. FPS, sudden lags etc.