This topic is now archived and is closed to further replies.


2D World collision with rectangles and triangles

Recommended Posts

JavaWorksForMe    122
I am writing a 2D platform game that uses polygons (specifically rectangles and right triangles) to define the solid portions of the world. Creatures have bounding boxes by which the collisions are tested. Initially, when I was only performing rectangle-to-rectangle collisions, I was able to separate the movement each frame into horizontal and then vertical pieces, but this method was drawn from a tile-based game which assumed you would never move more than one tile space per frame and you would never be overlapping more than four tiles at a time. Unfortunately, I find that this method has some flaws with rectangle-to-rectangle collision, and comes close to completely collapsing when triangles are introduced. Then, I thought about how sliding works in 3D, and I tried to think of my 2D world as an overhead representation of a 3D one, so slopes were just like angled walls, and walking straight into one should allow me to still walk forward but also push me away from the wall as I go. Still, I run into one of the same problems I had with the previous method. I will try my best to represent this with text and explain it as well.. Case 1: Assume you have a right triangle with a 45 degree slope, flush with the ground and a wall on its two broad sides (so it''s in a corner). Now, the player presses left or right, and so his desired direction is simply a horizontal one. It doesn''t recognize that the floor may be rising or falling beneath. In the case I have just described, this is n''t really a problem.. check for a collision in the direction we move, and find that we hit the wall. Fine, push the player back out of the wall, and then align his feet with the floor. Simple enough. Case 2: Assum again a right triangle flush with the floor and another rectangle, only this time the second rectangle is not a wall, but rather a box whose top is level with the peak of the slope. Again, the player is only desiring to move horizontally, but is moving veritcally as a consequence of the floor rising. In the case I have described, if there is ever a frame in which the player moves horizontally past the edge of the triangle, we don''t want to push him left or right out of the rectangle he coolides with, because that would signify a collision with a "wall" that didn''t (and shouldn''t) have happened. Still, we can''t push him out the top of the rectangle, because if we did, case 1 would be all screwed up. Poor ascii representations: Case 1: | \_ Case 2: _ \_ Honestly, I just don''t know how to handle this. An even more maddening case is when two triangles form a rising floor and lowering ceiling.. how do I determine if the player can horizontally make it into such a space? I know this should all be very easy, but I just can''t seem to figure it out. Any help would be greatly appreciated.

Share this post

Link to post
Share on other sites
oliii    2196
if you can calculate the slope of the floor (45 degrees, 60 degrees, ...), then you can have a threshold value, saying "if the slope is > 45 degrees, it's a wall, and push back the player. If the slope is < 45 degrees, move player and align with the floor).

even better, you can use a sliding algorithm, to change the velocity of the player, depending on the slope. So on a sharp slope, he won't move very fast.

say your player hits the segment [A, B]

Vector2 E = B - A; // the edge direction

Vector N = Vector(-E.y, E.x); // the normal of the edge

float n2 = N * N; // the normal's length squared

float nv = N * player.velocity; // the impact velocity (dot product)

player.velocity -= N * (nv / n2); // remove all impact velocity

and the player velocity would be a combination of key presses, and an ever present gravity acceleration, for example

player.acceleration = Vector(key.right() - key.left(), key.jump() - gravity);

player.velocity += player.acceleration;

[edited by - oliii on January 25, 2004 4:52:20 PM]

Share this post

Link to post
Share on other sites