# [sdl] help with pong collision

This is a discussion on [sdl] help with pong collision within the Game Programming forums, part of the General Programming Boards category; Im working on a collision system for a simple pong game and I'm having some troubles.. this is my collisionCheck() ...

1. ## [sdl] help with pong collision

Im working on a collision system for a simple pong game and I'm having some troubles..

this is my collisionCheck()
Code:
```int collisionCheck(SDL_Rect A, SDL_Rect B)
{
//The sides of the rectangles
unsigned int topA, leftA, bottomA, rightA;
unsigned int topB, leftB, bottomB, rightB;

// Calculate the sides for the SDL_Rect structs - Rect A
topA    = A.y;
leftA   = A.x;
bottomA = A.y - A.h;
rightA  = A.x + A.w;

// Calculate the sides for the SDL_Rect structs - Rect B
topB    = B.y;
leftB   = B.x;
bottomB = B.y - B.h;
rightB  = B.x + B.w;

// If Rect A is touching, or passing through, Rect B return true
if( ((topA == bottomB) || (bottomA == topB)) && ((leftA == rightB) || (rightA == leftB)) )
return 1; // if (touching)

// Otherwise, return false
else
return 0; // if (!touching)
} // collisionCheck()```
based off something I saw neo1 post

And here is my implementation inside a moveBall() function...
Code:
```/* PADDLE COLLISION,
*  OMG RUN BLARGH, BLARGH, BLARGH
*
*/
if ( collisionCheck( game->p1, game->ball ) || collisionCheck( game->ball, game->p2 ) )
{
// Multiply x component of slope by -1 to change sign (direction);
game->slope.dx *= -1;
} // if (bouncing off paddle)```
So the problem is that the ball moves (had some trouble with this at first) but it doesn't ricochet off the paddle the way it should.. instead it goes through it. Any thoughts?

edit: the original pong game was from a tutorial at I think oreilly's website

2. First of all you are calculating your "top" and "bottom" coordinates incorrectly.

SDL uses the coordinate system of (0,0) being at the top left of the screen (so unless you have defined your own coordinate system and are doing the correct viewport transformations, which I doubt, you need to take that into account). This means that the "bottom" is at:

A.x + A.h

and not:

A.x - A.h

Next, your "if" statement is incorrect. You are only checking to see if values are equal, and that will miss about 99&#37; of collision cases. Before I address that, however, what are p1 and p2? I assume "p" stands for "point", but that wouldn't make much sense because they are of type SDL_Rect which defines a rectangle.

The way in which I would do collision is to check each vertice of rectangle "A" to see if it is within rectangle "B". Something like this:

Code:
```for each vertice in A
if vertex_of_A.x is between B.x and (B.x + B.w) AND A.y is between B.y and (B.y + B.h)
return true
else continue```

3. a.x + a.w; // thats the right side btw
a.y - a.h; // thats what i use for the bottom..

anyways, you mean I should do something like this..
if (A.x <= (B.x + B.w) && A.y >= (B.y + B.h) )

which would be the same as..
if ((leftA <= rightB) && (topA >= bottomB))

that wouldn't work if thats the case since there are 2 paddles (later more) and the first part would always be true for the paddle on the right so it would end up bouncing in the middle of the screen furiously forever.

But, can I get some help with reasoning though, if the coordinate plane is the same as I learned in geometry then "A.y + A.h" would go up above the plane not down..
Code:
```                       y
. . . . . . . . . . . | 0, 2 . . . . . . . . .
. . . . . . . . . . . | 0, 1 . . . . . . . . .
. . . . . . . . . . . | 0, 0 . . . . . . . . .
----------------------+----------------------x
. . . . . . . . . . . | 0,-1 . . . . . . . . .
. . . . . . . . . . . | 0,-2 . . . . . . . . .
. . . . . . . . . . . |  . . . . . . . . . . .```

4. SDL's default coordinate system is thus:
Attachment 8149

This is how a lot of graphics packages are (not all of them however. OpenGL puts (0,0) at the center of the screen by default, but you can also define your own coordinate system quite easily in OpenGL. I don't know how DirectX does it). The reason many graphics packages do this is because of how CRT screens refreshed.

A CRT screen would have an electron gun that would start at the top left of the screen and move to the right, then go to the next row and do the same, until it hit the bottom of the screen. When it hit the bottom of the screen, it would "refresh" and go back to the top left. Since the screen can be represented as an array in memory (each pixel being an element of the array), it made sense to make the 0th element of that array be at the top left of the screen. Thus (0,0) became the top left of the screen and (Max X, Max Y) became the bottom right of the screen.

SDL uses this coordinate system.

http://lazyfoo.net/SDL_tutorials/lesson02/index.php

[/edit]

5. Ok, that makes a bit more sense, I was wondering why text was so hard to line up.

6. Here is a link on 2d collision detection:

http://www.gamedev.net/reference/art...article735.asp

7. Mmm.. still isnt helping... this is a cleaned up version of my original check..

Code:
```if( (leftA <= widthB) && (topA >= topB) && (bottomA <= bottomB) )
{
return 1;
}
if( (leftA >= (SCREEN_WIDTH - (widthC + widthA)) && (topA >= topC) && (bottomA <= bottomC) )
{
return 1;
}```
This one is really gross, the ball goes through the paddle before deflection leaving a nice black smear from the ball erasing itself also if the ball hits a corner, it goes right through it and lastly the ball has been known to bounce inside the paddle if you hit it just the right way...

now I really do want to fix this on my own I've been trying for a week now but I just don't get it.. (understanding the coordinate system is a help but not quite enough)

8. Well your conditions in your if-statement are still wrong. Where did these width variables suddenly come from?

The first function on that link I posted for you does exactly what you want to do. I will repost it here just in case you missed it:

Code:
```short int Sprite_Collide(sprite_ptr object1, sprite_ptr object2) {

int left1, left2;
int right1, right2;
int top1, top2;
int bottom1, bottom2;

left1 = object1->x;
left2 = object2->x;
right1 = object1->x + object1->width;
right2 = object2->x + object2->width;
top1 = object1->y;
top2 = object2->y;
bottom1 = object1->y + object1->height;
bottom2 = object2->y + object2->height;

if (bottom1 < top2) return(0);
if (top1 > bottom2) return(0);

if (right1 < left2) return(0);
if (left1 > right2) return(0);

return(1);

};```
There are a couple tweaks you have to do (change it to use the classes/types you are using and also change the return values to correspond with your usage), but nothing major. That is essentially the function you want. It was the first function on the gamedev article.

9. There must be something wrong with something else in my code because that still doesn't work. Actually I'll compile a win vs so you can see what I mean.

/edit
this is the working one with the previous checks..
http://www.sendspace.com/file/whgeov

And the one with the algorithm you posted
http://www.sendspace.com/file/g7b2a1

controls:
a - left up
z - left down
' - right up
/ - right down
space - pause/start