9
\$\begingroup\$

I've recently picked up monogame and am working on a simple top down game to get me started and learn the basics.
I've got the movement and the rotation to follow the mouse sorted out but I'm stuck with the collisions.
What I want to know, basically, are two things:

  1. What would be the best way to handle collisions? I know that Rectangle.Intersects(Rectangle1, Rectangle2) returns the overlapping rectangle, but, as the movement in top down is on x/y axis I'd like to know where the collision is happening so I can create kind of "wall sliding" where the player doesn't get stuck at the wall.
    Is checking the players x/y coordinates against solid objects coordinates, then throw the player to his previous position if he enters the bounds of a solid object really the best approach? What would you suggest?
  2. What would be the best way to apply collisions to all of the solids, npc's etc.? I'm currently thinking of creating a gameObject class that all of the objects will inherit from and just handle the collisions there.

Thanks for reading and hope that someone can give me some tips.

\$\endgroup\$
1

3 Answers 3

10
\$\begingroup\$

Generally the way most physics engines handle this problem is by separating the intersecting objects.


So if your objects are represented by rectangles (also known as "Axis Aligned Bounding Boxes"), and they collide on a given frame like so:

Collision


You would then measure the amount of interpenetration on each axis. Then select the axis with the smallest amount of interpenetration, and separate the objects along that axis.

Separate


You would then register this as a "collision" and apply appropriate dynamics.

For example, if you want to slide along the wall, you would just zero-out the velocity on the axis you separated on (the X axis, in the above illustration), leaving the velocity on the other axis alone.

But you could also apply friction, or make the objects bounce apart.


Here is an excellent, interactive tutorial that shows how to do this in a lot more detail.

Although, if you're going to go far down this path (anything more than simple AABB-collisions), you might want to consider using an existing engine like Velcro Physics (formerly Farseer Physics).


Finally, a note on implementation (if you don't go the Farseer route): Rectangle uses int values, which aren't really appropriate for doing physics in most cases. Consider making your own AABB class that uses float instead.

Your second question is pretty well answered by my old answer on game architecture over here, so I won't repeat it here.

\$\endgroup\$
2
  • \$\begingroup\$ Maybe there is something i dont understand, but isn't this approach flawed? I have illustrated the problem here: jmp.sh/jEW2lvR It would result in some weird behaviour at times. \$\endgroup\$
    – BjarkeCK
    Commented May 20, 2014 at 19:14
  • \$\begingroup\$ @BjarkeCK: Yes, you need to do extra work to handle cases like that. I am not well versed enough to fully explain how to handle them properly (I just use Farseer and call it a day). Possibly take a look at "Section 5" of this link. \$\endgroup\$ Commented May 21, 2014 at 5:05
1
\$\begingroup\$

1: I have been working on a relatively simple top-down action game as well, and after a week(-s?) of struggle, I ended up using a sort of step-by-step approach to collision detection and response. Main reason being that using the shortest amount of interpenetration would in some cases result in "teleportation" to a new position that the moving object was not in previously.

so, when an object wants to move,

  1. I create a boundingbox of the object at object's position + moveAmount vector, creating a sort of target bounding box
  2. then I check this target bounding box for any intersects with the game objects, tiles, etc. if there are any, I add them to a new list, that holds all potential collisions for current frame
  3. if there are no intersections, object moves. but if there's an intersection,
  4. I split up the wanted movement into "steps". then I run a loop for the number of steps I have. each step moves the object just for 1 pixel in x and y direction.
  5. for each step I check every new projected position for collisions, if nothing, I add step's move vector to the final move vector.
  6. if there's a collision (intersects returns true), I compare the previous position (position at previous step) of moving object with the thing it's colliding with.
  7. depending on this previous position I halt the movement along the conflicting axis (e.g., if the moving object comes at the colliding object from above, I set y value of move vector to 0 etc.).
  8. I repeat this for every consecutive step, adding the adjusted step vectors together to make one final adjusted moveAmount vector that I can safely use for moving the object without any collisions happening.

this approach both ensures that object "bounces" back to correct previous position and it allows for sliding against the walls, objects, whatever.

2: I myself use a static collision class that can be used by whatever. it holds collision detection and vector adjustment methods, that can be called by pretty much anything. whether these methods are called from a "master" game class or by some object subclass doesn't really matter in my case, because the collision class makes a new list every frame for all rectangles the moving object is intersecting with. these rectangles might be from tiles, decorations, NPCs, whatever that has boundaries and is collidable, basically. this means that the bare necessity for all game objects that are collidable is to have boundaries rectangle. if they have that, collision class will handle the rest.

hope this was understandable.

\$\endgroup\$
0
\$\begingroup\$

1: I successfully used a technique to solve this: using the speed and position you can discover the collision, and iterate back until the position is very close to the exact collision point.

It's not part of the answer for your first question, but if you have a lot of objects that can collide with each other you should use quadtrees to improve performance. There is a very good tutorial with a lot of examples here.

2: I always recommend Entity-Systems.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .