[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. #1
    Registered User
    Join Date
    May 2008
    Posts
    5

    [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 ) )
            {
                    // Add sound effect here?
                    // 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
    Last edited by caffeinated; 05-13-2008 at 06:53 AM.

  2. #2
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,738
    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% 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
    My Website

    "Circular logic is good because it is."

  3. #3
    Registered User
    Join Date
    May 2008
    Posts
    5
    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. #4
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,738
    SDL's default coordinate system is thus:
    Name:  coords.PNG
Views: 1408
Size:  4.3 KB

    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.

    [edit]

    This link talks about the SDL coordinate system as well:

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

    [/edit]
    Last edited by DavidP; 05-13-2008 at 08:41 AM.
    My Website

    "Circular logic is good because it is."

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    5
    Ok, that makes a bit more sense, I was wondering why text was so hard to line up.

  6. #6
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,738
    Here is a link on 2d collision detection:

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

    "Circular logic is good because it is."

  7. #7
    Registered User
    Join Date
    May 2008
    Posts
    5
    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. #8
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,738
    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.
    My Website

    "Circular logic is good because it is."

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    5
    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
    Last edited by caffeinated; 05-14-2008 at 02:07 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Some collision handling fun
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 04-13-2008, 08:45 AM
  2. Allegro Pong Collision Problems
    By gillypie in forum Game Programming
    Replies: 4
    Last Post: 12-30-2007, 05:05 AM
  3. Pong Clone Collision Allegro
    By gillypie in forum C++ Programming
    Replies: 1
    Last Post: 12-29-2007, 01:42 AM
  4. Collision Detection Problems
    By Dark_Phoenix in forum Game Programming
    Replies: 1
    Last Post: 12-17-2006, 02:25 PM
  5. Replies: 4
    Last Post: 05-03-2002, 09:40 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21