More Collisions

Sage
Posts: 1,066
Joined: 2004.07
Post: #1
Seems like collisions are some of the hardest things in programming. I searched the forums a bit and learned some things but none really helped solve my imediate problem. I learned when to use global functions and member functions. I learned various (probably 5) different ways of detecting collisions in both C/C++ and Objective-C. In my collision code, I simply take a side of one box and see if it falls between a side and predetermined distance into another box. Here's a bit of the code:

This code is for a sidescroller I'm making with SDL/OpenGL (though maybe porting to Cocoa/OpenGL). The problem is that with my gravity code there are occasions (not all the time) where the player falls through objects. I'm assuming it's because it's going to fast to detect the collision the way it is.

Note: GetCSide() is a dumb way of calling this. Basically each object can have up to four sides for collisions which are set in an array of member variables. This way some things can have collisions on the top and sides but not the bottom such as some platforms similar to Mario games. TILE_SIZE is simply my defined size for a tile in the game. COLLISION_CUSHION is the defined portion of a tile into the player that is used for collision detection. Everything else should be pretty self explanatory. GetX,Y,Z are for coordinates. GetW,H are for dimensions. Set functions simply set their respective variable

Code:
void CheckCollisionPG(Player &p, Ground &g)
{
    if (p.GetZ()==g.GetZ()) //if we're on the same z plane
    {
        for (int i=0; i<=4; i++)
        {
            switch (g.GetCSide(i))
            {
                case TOP :
                {
                    if ((p.GetX()+p.GetW()>=g.GetX()) &&
                        (p.GetX()<=g.GetX()+g.GetW())) //if we're aligned on the Y axis
                    {
                        if ((p.GetY()<=(g.GetY()+g.GetH())) &&
                            ((p.GetY()+(COLLISION_CUSHION*TILE_SIZE))>=(g.GetY()+g.GetH())))
                        {
                            p.SetY(g.GetY()+g.GetH()+.0001);
                            p.SetDescent(0);
                        }
                    }
                    break;
                }
                case BOTTOM :
                {
                    if ((p.GetX()+p.GetW()>=g.GetX()) &&
                        (p.GetX()<=g.GetX()+g.GetW())) //if we're aligned on the Y axis
                    {
                        if ((p.GetY()+p.GetH()>=g.GetY()) &&
                            (p.GetY()+p.GetH()-(COLLISION_CUSHION*TILE_SIZE)<=g.GetY()))
                        {
                            p.SetY(g.GetY()-p.GetH()-.0001);
                        }
                    }
                    break;
                }
                case LEFT :
                {
                    if ((p.GetY()+p.GetH()>=g.GetY()) &&
                        (p.GetY()<=g.GetY()+g.GetH())) //if we're aligned on the X axis
                    {
                        if ((p.GetX()+p.GetW()>=g.GetX()) &&
                            (p.GetX()+p.GetW()-(COLLISION_CUSHION*TILE_SIZE)<=g.GetX()))
                        {
                            p.SetX(g.GetX()-p.GetW()-.0001);
                        }
                    }
                    break;
                }
                case RIGHT :
                {
                    if ((p.GetY()+p.GetH()>=g.GetY()) &&
                        (p.GetY()<=g.GetY()+g.GetH())) //if we're aligned on the X axis
                    {
                        if ((p.GetX()<=g.GetX()+g.GetW()) &&
                            (p.GetX()+(COLLISION_CUSHION*TILE_SIZE)>=g.GetX()+g.GetW()))
                        {
                            p.SetX(g.GetX()+g.GetW()+.0001);
                        }
                    }
                    break;
                }
            }
        }
    }
}


If anybody can help me fix this efficiently or offer up some C/C++ collision code for a sidescroller, I'd appreciate it.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #2
SimReality/Nick Wrote:Seems like collisions are some of the hardest things in programming.
without a doubt.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #3
skyhawk, when checking for collisions, do you find the current position and next position and see if a hypothetical wall falls between them or do you use a constant like in my example? or do you do something else?
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #4
It all depends, you can chose to do it in a million and one ways. Usually, you do continuous time detection for particles (which have no volume and move fast) and discrete time detection for boxes and triangle meshes.

Of course the two approaches can be combined, and when you take space partitioning into account, lemme tell you it ain't pretty.

All I can suggest is to have a pencil and paper (lots of paper) handy while working on collision detection, to draw out scenarios and solve them by hand and pseudo-code.
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #5
I'm about to implement collision detection myself, and it needs to work with walls and balls (the object moving around is a ball). I've been reading up on it, and I think I've got a good idea of how to approach it, but since my animation loop is interval-based, I'm thinking I should check the projectiles' path so I don't miss a collision if the framerate drops for some reason... Good idea?
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #6
SimReality/Nick Wrote:skyhawk, when checking for collisions, do you find the current position and next position and see if a hypothetical wall falls between them or do you use a constant like in my example? or do you do something else?
I use the current position and the last position
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #7
skyhawk Wrote:I use the current position and the last position
I think I'm going to give that a try to see if I get better results.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #8
After giving the y-lasty idea a try I have good results on all sides except 1. I don't know why. Here is the code for that collision. X,Y are coordinates of the lower left corner of the quad. W,H are the width and height, respectively. LastY,LastX are the last Y and X positions, respectively. p is the player and g is the ground.

Code:
if ((p.GetX()+p.GetW()>=g.GetX()) &&
    (p.GetX()<=g.GetX()+g.GetW())) //if we're aligned on the Y axis
    {
        if ((p.GetY()<=(g.GetY()+g.GetH())) &&
         (p.GetLastY()>=(g.GetY()+g.GetH()))) //if the last Y value was above the top of the ground and the new Y is below
    {
        p.SetY(g.GetY()+g.GetH()+.0001); //set the Y to be on the ground
        p.SetDescent(0); //remove our rate of descent
    }
}
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Elastic Collisions in Objective C Mattonaise 4 6,986 May 13, 2011 11:40 PM
Last Post: Lazer
  Sometimes collisions work, sometimes they don't. t3knomanser 5 3,271 May 13, 2006 03:00 PM
Last Post: Iceman
  Avoiding Collisions DM6 4 3,804 Jul 31, 2004 11:31 AM
Last Post: FCCovett