3
\$\begingroup\$

Well I'm trying to create a pong clone using SDL and I had some problems with the frames and some times the ball would go through the paddles despite the fact that at other times the collision worked perfectly. So I searched it a bit and I came to the conclusion that it was because in one frame the ball was already through the paddle and in another frame the ball was not or something like this. So thought that if I would manually adjust the position of the ball, like move it a couple of pixels away the moment it hits a paddle or the walls too, this would solve the problem. But now when the ball goes right past a paddle its movement is getting weird and it goes right in the playing field. Gif for reference also some code if you want to look it . I feel bad for doing the whole collision like these but I couldn't think some other way. Please enlighten me if there are better ways to do it that I can avoid the frame problem I mentioned above. Here is the code that handles the ball's movement :

   void Ball::move(float xLeftPaddle, float yLeftPaddle,float xRightPaddle, float yRightPaddle, Uint32 deltaTicks)
{

    y +=  yVelocity * ( deltaTicks / 1000.f );
    x +=  xVelocity * ( deltaTicks / 1000.f );

    if(   y + BALL_HEIGHT > SCREEN_HEIGHT )
    {
        x = x-1;
        y = y-1;    
        yVelocity = -yVelocity;

    }
    else if( y < 0 )
    {
        x = x+1;
        y = y+1;
        yVelocity = -yVelocity ;        
    }   
    else if(x + BALL_WIDTH >= xRightPaddle && y <= yRightPaddle + PADDLE_HEIGHT && y >=yRightPaddle  )
    {
        x = x-1;
        y = y-1;
        xVelocity = -xVelocity;

    }
    else if( x <= xLeftPaddle + PADDLE_WIDTH && y <= yLeftPaddle + PADDLE_HEIGHT && y >= yLeftPaddle)
    {
        x = x+1;
        y = y+1;

        xVelocity = -xVelocity ;
    }   
    else if(x < 0 || x > SCREEN_WIDTH)
    {
        x = SCREEN_WIDTH/2;
        y = SCREEN_HEIGHT/2;
    }

}

\$\endgroup\$
  • 4
    \$\begingroup\$ You don't check if the ball has past the paddle. This allows you to "hit" the ball when it's already gone past the paddle. \$\endgroup\$ – MichaelHouse May 11 '14 at 17:17
  • \$\begingroup\$ Can you give me any pointers on how to fix this ? Should I add two more if conditions for each paddle to check this ? \$\endgroup\$ – user3385993 May 11 '14 at 17:20
  • \$\begingroup\$ You want to check if the position you're moving to next is inside the bounds of the paddle. Similar to how you ensured the ball was between the top and bottom of the paddle, you need to check to ensure it's between the front and back too. \$\endgroup\$ – MichaelHouse May 11 '14 at 17:22
2
\$\begingroup\$

Most reliable is to not check positions but movement: use your motion vector to check whether the ball's line of movement intersects with the paddle. This way it never goes through the paddle even if FPS is slow / ball movement really fast. We achieve this by using a physics library (Bullet) in our Pong (https://github.com/playsign/PongThreeJS) but it is well doable with own code too.

If your movement never gets too fast compared to the update rate (FPS) then what was discussed earlier works too.

\$\endgroup\$
  • \$\begingroup\$ I fixed it using the way that Byte56 suggested because it's simple enough to do the trick. Thanks for the heads up about Bullet though. \$\endgroup\$ – user3385993 May 12 '14 at 23:21
  • \$\begingroup\$ Right - should be fine for relatively slow movement per frame. Do note that if you'll end up needing the motion vector check you don't necessarily need bullet (a big general purpose physics lib, ammo.js is the emscripten compile of it) for it but can just check it simply for pong in own / some simple intersection check js code. \$\endgroup\$ – antont May 12 '14 at 23:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.