Pong with SDL collision help

Started by
4 comments, last by endless11111 11 years, 11 months ago
I am currently trying to learn to use SDL, and right now i am trying to make a pong game. i know how to do the collision, and it works fine with the front or back of the ball with the front or back of the two paddles, but when it hits the top or bottom of the paddle's the ball goes through the paddles. i was wondering if anyone knows a way to stop the ball from going inside the paddles. also if you dont move the ball bounces off properly, it only happens when you move. here is my ball's movement code.
void ball::move(SDL_Rect rwall, SDL_Rect lwall)
{
//move the ball and limit the speed
ballbox.x += velx;
ballbox.y += vely;
//check to see if ball hits any of the walls
if(ballbox.x <= 0) //left wall
{
ballbox.x = startx;
ballbox.y = starty;
velx = -velx;
rpoints++;
}
else
if(ballbox.x + ballbox.w >= screen_width)//right wall
{
ballbox.x = startx;
ballbox.y = starty;
velx = -velx;
lpoints++;
}
// make the ball bounce if it hits the top or bottom
if(ballbox.y <= 0)
{
ballbox.y -= vely;
vely = -vely;
}
else
if(ballbox.y + ballbox.h >= screen_height)
{
ballbox.y -= vely;
vely = -vely;
}
//check for collision with the player's pads
//collision with front or back of right pad
if((ballbox.x + ballbox.w >= rwall.x) && (ballbox.x <= rwall.x + rwall.w) && (ballbox.y + ballbox.h >= rwall.y +5) && (ballbox.y <= rwall.y + rwall.h -5) )
{
ballbox.x -= velx;
velx = -velx;
}
else
//collision with top of right pad
if((ballbox.x + ballbox.w >= rwall.x) && (ballbox.x <= rwall.x + rwall.w) && (ballbox.y + ballbox.h >= rwall.y) && (ballbox.y + ballbox.h <= rwall.y + 5))
{
ballbox.y -= vely;
vely = -vely;
}
else
//collision with bottom of right pad
if((ballbox.x + ballbox.w >= rwall.x) && (ballbox.x <= rwall.x + rwall.w) && (ballbox.y <= rwall.y + rwall.h) && (ballbox.y >= rwall.y + rwall.h - 5))
{
ballbox.y -=vely;
vely = -vely;
}
else
//collision with front or back of left pad
if((ballbox.x + ballbox.w >= lwall.x) && (ballbox.x <= lwall.x + lwall.w) && (ballbox.y + ballbox.h >= lwall.y +5) && (ballbox.y <= lwall.y + lwall.h -5) )
{
ballbox.x -= velx;
velx = -velx;
}
//collision with top of left pad
if((ballbox.x + ballbox.w >= lwall.x) && (ballbox.x <= lwall.x + lwall.w) && (ballbox.y + ballbox.h >= lwall.y) && (ballbox.y + ballbox.h <= lwall.y + 5))
{
ballbox.y -= vely;
vely = -vely;
}
//collision with bottom of left pad
if((ballbox.x + ballbox.w >= lwall.x) && (ballbox.x <= lwall.x + lwall.w) && (ballbox.y <= lwall.y + lwall.h) && (ballbox.y >= lwall.y + lwall.h - 5))
{
ballbox.y -=vely;
vely = -vely;
}
}
Advertisement
Imagine the following scenario: say your ball is at point that we will call P. The paddle moves such that it encloses P. The ball now moves to point P', which as it happens is also inside the paddle. The ball tries to "bounce", but a fundamental invariant (the assumption that the ball starts inside the bounds and outside the paddles) is broken, and the code does not behave as it was intended.

Imagine the following scenario: say your ball is at point that we will call P. The paddle moves such that it encloses P. The ball now moves to point P', which as it happens is also inside the paddle. The ball tries to "bounce", but a fundamental invariant (the assumption that the ball starts inside the bounds and outside the paddles) is broken, and the code does not behave as it was intended.


i see, that makes sense, but how do i stop the ball and paddle from overlapping in the first place? i tried making the balls y position above or below the paddle's position, but the ball always ends up in the paddle
You could do a simple projection test on the ball. You have current position and velocity of the ball. So check if the balls next position will intersect the paddle, and do an appropriate response depending on what you want.
The most obvious thing that could go wrong is if you don't do collision tests when moving the paddles. In that case it would be kind of vital to move the ball _after_ the paddles.

Even then, you can't just undo the balls movement and reverse it's velocity. What if the ball was moving horizontally above the paddle and the paddle hit the ball?

Another issue with checking for intersection rather than actual collision is that if your ball ever travels fast enough to move from in front of the paddle to behind the paddle in a single frame, you would never handle that and the ball would just zip right through the paddle (chances are that the game would be unplayable anyway, if the ball every moves that fast).

It also depends on just how correctly you want to handle corner cases. If you want to handle hitting the corner of the paddle and bouncing off in a correct way, then things will require to calculate the actual point of collision (depending on the movement of ball AND paddle) and using the vector from this point to the balls center as axis to mirror the angle.

Also, just undoing the entire motion is technically wrong and will almost always move the ball too much. The only distance it will move away from a wall/paddle after colliding is the _remaining_ travel distance. Imagine the ball moving 100 pixels per frame and being 100 pixels from the paddle. You now make it stop and revert 100 pixels before it even touches the paddle. Though if you're game is running fast enough, the steps per frame should be very small and nobody might ever notice it.


In other words, you need to decide if you want it to be simply and easy to code or 100% physically correct (or let's say 90%, nobody wants to deal with material properties, deformation during impact, air friction and other stuff).
f@dzhttp://festini.device-zero.de

The most obvious thing that could go wrong is if you don't do collision tests when moving the paddles. In that case it would be kind of vital to move the ball _after_ the paddles.

Even then, you can't just undo the balls movement and reverse it's velocity. What if the ball was moving horizontally above the paddle and the paddle hit the ball?

Another issue with checking for intersection rather than actual collision is that if your ball ever travels fast enough to move from in front of the paddle to behind the paddle in a single frame, you would never handle that and the ball would just zip right through the paddle (chances are that the game would be unplayable anyway, if the ball every moves that fast).

It also depends on just how correctly you want to handle corner cases. If you want to handle hitting the corner of the paddle and bouncing off in a correct way, then things will require to calculate the actual point of collision (depending on the movement of ball AND paddle) and using the vector from this point to the balls center as axis to mirror the angle.

Also, just undoing the entire motion is technically wrong and will almost always move the ball too much. The only distance it will move away from a wall/paddle after colliding is the _remaining_ travel distance. Imagine the ball moving 100 pixels per frame and being 100 pixels from the paddle. You now make it stop and revert 100 pixels before it even touches the paddle. Though if you're game is running fast enough, the steps per frame should be very small and nobody might ever notice it.


In other words, you need to decide if you want it to be simply and easy to code or 100% physically correct (or let's say 90%, nobody wants to deal with material properties, deformation during impact, air friction and other stuff).


then for the actual collision should i use a general collision function to detect the collision?

This topic is closed to new replies.

Advertisement