2d collision finding out which side of object you have collided with

Started by
6 comments, last by Omar Alvi 19 years, 11 months ago
Hello, I am making a 2d scrolling game and having some problems with the colision detection. Well its easy to check if objects have collided with each other. But i want to get some additonal info when the objects collide. Lets say when the hero collides with an object i want to know if it has collided with that object from bottom or above or sides. Its important for me to triger different events. Like when hero jumps on the enemy the enemy dies and if the hero touches the enemy from any other side the hero dies. Hope to hear from you guys soon. Thank you Omar Alvi
Advertisement
You could try keeping the location the hero was in the last game loop, then use that to determine the direction of travel and hence a likely direction of impact.
------------------------------------------[New Delta Games] | [Sliders]
Hmmm.

Okay, lets say your badguy has a rectangle for its collision. Then your player''s character( Lets call him Mario, for arguments sake...) has a single point(x,y) for his position. Surrounding this point is his own collision rectangle.

So now we test to see if the rectangles overlap. If they do - we carry on with the next test to see which side of the badguy''s collision rectangle Mario''s position(x,y) collided with.

Now obviously, each side of the badguy''s rectangle will consist of two points. You have four sides - therefore four lines in all in which to test for collision.

Before the character has moved - you record his position, which we will call the "origin". Then once you have finished moving him, he will have a new position - the "destination". With these two points you have another line - you will test this line against each of the baguys collision rectangle''s lines.

Now here is the hard part - testing to see if two lines intersect! Theory & maths for test for line intersection is covered in Andre LaMothes "Tricks" books, but is quite difficult to grasp.

Anyway, once you know which of the lines intersect with Mario''s line - you know which side collision has taken place.

Thats the jist of it anyway.

Good luck!

Languages; C, Java. Platforms: Android, Oculus Go, ZX Spectrum, Megadrive.

Website: Mega-Gen Garage

Just keep track of the player''s previous position and compare. If the player was last seen above the enemy sprite, it''s pretty unlikely that he''d bump the enemy on the side the next frame.

Alternatively, you can check where the collision occures on the rectangle. A rough implementation would involved comparing the player position and the enemy position. if PlayerY > EnemyY, collision = from above; that sort of thing. It''s rough and probably not too functional but for a basic game it should perform just fine.
Oh! Another way to do it is this...

The badguy and Mario have two collision rectangles each! So far so good....

Lets say the first rectangle is the upper body of the character, and the second is the lower body of the character...

if the "lower body" of Mario collides with the "lower body" of the badguy - Mario dies. However, if the "lower body" of Mario collides with the "upper body" of the badguy - the badguy dies.

Not perfect, but a simple alternative!

Languages; C, Java. Platforms: Android, Oculus Go, ZX Spectrum, Megadrive.

Website: Mega-Gen Garage

Hmmm, Thanks people for your useful suggestions. Anry i like the first approach that u told me about. Hmmm will think about using that in my game....It seems that it will do the trick. Thanks a lot.

Omar Alvi
No problem.

Good luck with the game!

Languages; C, Java. Platforms: Android, Oculus Go, ZX Spectrum, Megadrive.

Website: Mega-Gen Garage

there''s a simpler method Calculate the minimum overlap between the two rectangles, that will tell you wich side collided.

// test rectangle A & B for collision.// returns of they have collided, and which way and how far // you have to push rectangle A so rectangles stop intersecting.bool Collide(const RECT& A, const RECT& B, POINT &PushBack){    float xneg = B.minx - A.maxx; // if positive no intersection    float yneg = B.miny - A.maxy; // if positive no intersection    float xpos = B.maxx - A.minx; // if negative no intersection    float ypos = B.maxy - A.miny; // if negative no intersection    if (xneg > 0.0f || yneg > 0.0f)        return false;    if (xpos < 0.0f || ypos < 0.0f)        return false;    // select the minimum overlap distance along both axes    float x = xneg;    if (-xneg > xpos)        x = xpos;    float y = yneg;    if (-yneg > ypos)        x = ypos;        // select the minimum of the overlap distance between axes    if (fabs(x) < fabs(y))        y = 0.0f;    else        x = 0.0f;    PushBack.x = x;    PushBack.y = y;    return true;}


if the pushback distance is too big, or incompatible with the velocity of the character (i.e. of the velocity goes in the same direction of the push back vector), it means that the character traveled so fast, he ended up on the other side of the box after a frame. In that case, track back the character position to get a more accurate collision and push back vector.

Everything is better with Metal.

This topic is closed to new replies.

Advertisement