2d collision finding out which side of object you have collided with
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
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.
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!
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!
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.
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!
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!
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
Omar Alvi
there''s a simpler method Calculate the minimum overlap between the two rectangles, that will tell you wich side collided.
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.
// 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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement