1
\$\begingroup\$

So I'm making a game which is based on randomly generated rooms and I need a way to keep the player inside them and make the player glide when he collides with the room's bounds. I currently have a SAT algorithm in place to detect collisions, but I don't know how to do collision resolution for being inside rooms.

Full code here

sf::Vector2f Collision::GetMtv()
{
    return (Mtv(small, smallestPerpendicular[smallestIndex]));
}
\$\endgroup\$
1
\$\begingroup\$

How I would do it:

  • Step 1: define rectangles for the bounds of each room and hallway. Now imagine these rectangles as safe areas where the player can be. "Out of bounds" would be declared as any position in which the player is not fully contained in any of the rooms or hallways. Here's a picture as a demonstration:

Player rectangles

Now, before we go further, you must note one important fact. If the player is between a room and a hallway, it will be declared out of bounds. So to avoid this problem, you must define your hallway rectangles overlapping into both rooms by a little bit more than the maximum size of the player.

  • Step 2: every time you move the player on the X axis, keep track of a "last X" variable. If the player steps out of bounds, then restore the player's X value to that variable. Do the same for Y movement.

  • Step 3: One final note is that if it is easier to do so, you can instead define rectangles for all of the walls (aka black space). Then, you reverse the collision check per rectangle to "if Rx1 > Lx2 && Lx1 < Rx2 && Uy1 < Dy2 && Dy1 > Uy2, then there is a collision with that rectangle (the wall)".

  • Step 4: Finally, if you want pixel perfect collision detection: well, pixel perfect collision is very expensive. However, in some cases it is worth it. You should really check out Riemer's 2D collision tutorial - it's written in C# instead of C++ but it's really straightforward and easy to understand - you should at least be able to use the concept if not the exact code. http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Coll_Detection_Overview.php

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ What about smooth collision resolution without jitter effects, how would i go about that? \$\endgroup\$ – The Dude Apr 18 '15 at 21:05
  • \$\begingroup\$ Also this only works if the origin of the rects are in the middle, what if the origin isn't? \$\endgroup\$ – The Dude Apr 18 '15 at 23:08
  • \$\begingroup\$ The origin can be anywhere as long as you still keep track of the sides of the rectangle. If the origin is offcentered then you set the rectangle to that origin plus or minus some vector2. For example, if you needed a rectangle at 0, 0, and the player's origin was at 5, 5, you'd calculate the rectangle at (playerpos.X - 5, playerpos.Y - 5). Also for the jitter effects... what jitter effects? You resolve the collision in the same frame then there won't be any jitter effects. Move. If collision, move back. All in the same frame. \$\endgroup\$ – Superdoggy Apr 18 '15 at 23:42
  • \$\begingroup\$ I mean, how do i obtain the sides of the rectangles if their origin is off-centered, it becomes much trickier to apply collision and i can't set the origin to their middle, because that would wreck the map generation. \$\endgroup\$ – The Dude Apr 19 '15 at 9:36
  • \$\begingroup\$ Somehow, you're drawing the map. All you need is the x position of the left side and the right side and the y position of the top side and bottom side of each rectangle. Like I said, somehow you're drawing the map. If you have to, dump all the data into a gigantic list at initialization. In fact - what's all this? github.com/MrCappucino/Dungeon/blob/master/src/Rooms.cpp it looks like you know where the walls of each rectangle are here, can't you add that data to a list of rectangles? \$\endgroup\$ – Superdoggy Apr 19 '15 at 13:04
0
\$\begingroup\$

Great work that you are doing here :D.

The thing about advanced collision detection or any technical aspect of programming is getting it done right.

To do so, you must separate the mechanic you want, then make it in a separate environment, then test it then port it into your game.

in this case, you want to make a separate SAT collision demo first then implement that into your game.

Take a look at the interactive demo HERE.

However in your case,

enter image description here

since you only have squares why not choose a simpler approach?

You don't need to go for SAT, because if your "squares" are all going to be laid nice and pretty horizontally, then you have no need for diagonal or any other collision test for rotated shapes.

Why don't you try AABB? Youtube

If I were you, I would put square walls at the edge of map.

AABB is a very simple and popular technique. You would be able to find abundance of resources to learn it.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The problem is that each of my corridors have different origin points, because each time a new corridor is generated, it's origin is next to the earlier room's 1/4 sides (left/right/top/bottom), then collision becomes tricky. Also collision response is something i can't figure out for some reason, i always get jittering. \$\endgroup\$ – The Dude Apr 19 '15 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.