0
\$\begingroup\$

I can never seem to get this right, well polished at least. I'm creating a top down game in XNA, and collision has always been an issue for me to do properly. Detecting collision is fine, but resolving it is where I get messed up.

My approach so far:

  • Loop through rectangles polled by a quad tree
  • check if these rectangles intersect with the player
  • if yes then undo the velocity that we just applied to the player
  • if no then do nothing

This approach is less than ideal but it's close, I'm trying to allow players to move along the wall even if they're applying the force on the wall.

For example: if the player collides against a vertical wall, they should be able to move up and down even if they are still trying to move left/right.

I can't seem to find a good way to do this. Maybe I'm overthinking, but I tried doing vector subtraction on the centre's of the player and tile and seeing where the vector pointed. But that didn't give me much helpful information. I tried seeing if it was the x-axis or y-axis that was colliding but that didn't work as the player is bigger than the tiles.

Is there a way to find which axis is colliding so I can undo velocity on that specific axis?

\$\endgroup\$
  • 1
    \$\begingroup\$ You shouldn't ask for best practices, and I shouldn't answer, but the truth is just use middleware :) \$\endgroup\$ – MickLH May 8 '14 at 23:16
  • \$\begingroup\$ I think you'll like the Separating Axes Theorem. (Different ways exist, depending on your needs, but SAT is a useful introduction.) Could you describe more what your needs are? Is it just rectangle-to-rectangle collision? How exactly does your current method work? \$\endgroup\$ – Anko May 8 '14 at 23:17
  • \$\begingroup\$ @Anko Thanks for the link! It's just rectangle to rectangle collision, I have a quadtree poll for rectangles based on the player's position. So iirc it would be the player that could collide with at most 8 objects (not at the same time). I was trying to get it so your player could move in any direction but the collidable object. \$\endgroup\$ – Thegluestickman May 8 '14 at 23:26
  • \$\begingroup\$ @MickLH Whoops, sorry I wasn't sure if that was allowed. \$\endgroup\$ – Thegluestickman May 8 '14 at 23:27
  • \$\begingroup\$ @Thegluestickman You can probably salvage this question. You need to reword it and provide more information about how you're doing collision detection, so that it is a specific question with a specific answer. But MickLH is right - you probably should be using middleware like Farseer (although I can't firmly recommend it, because, again, you haven't provided enough specific details about what you are trying to achieve). \$\endgroup\$ – Andrew Russell May 9 '14 at 1:18
2
\$\begingroup\$

Take a look at the SAT Tutorial that Anko linked in comments. The tutorial explains everything you need to know.

Specifically, what you want to find is the "minimum penetration vector" (that tutorial calls it the "projection vector" and shows it as a purple arrow).

Your collision response, right now, is to cancel out all movement - which is obviously not working. What you need to be doing, as collision response, instead, is "separation" (not the same thing as the "separating axis" in SAT).

As the tutorial says, you take the minimum penetration vector and move your player backwards by that vector to separate them from the world geometry.

Because you've now "stopped" in that direction, you need to clear the velocity in that direction. Do this by projecting your velocity vector onto the tangent of the minimum penetration vector. (You could also add in further response such as bouncing and friction.)

\$\endgroup\$

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.