# Why does this collision detection & resolution code only work for one side?

I am having a bit of trouble with my collision detection. It only works correctly for the right side, meaning, if I enter the tile from any other side, it brings me to the right side.

Here is my code:

const float spriteWidth = 5.0f;
const float spriteHeight = 14.0f;

float x = position.X;
float y = position.Y;

if (bounds.Intersects(tileBounds))
{
if ((x + spriteWidth) > tileBounds.Left)
position.X = tileBounds.Left - 5;
if (x < tileBounds.Right)
position.X = tileBounds.Right;
if ((y + spriteHeight) < tileBounds.Bottom)
position.Y = tileBounds.Bottom;
if (y > tileBounds.Top)
position.Y = tileBounds.Top - 14;
}


I just don't see why it would do that. I am calling this function from the Game1.cs Update function, FYI.

And it only works for one tile out of a possible many, but that's for a later question...

Does anyone have an idea why it would do this? Thank you very much.

• Hi Fiona, I voted to close since you're asking us to debug your code for you, which is off topic for GDSE. Your best bet is to get practice using a debugger. If you step through the code and watch what is happening, it should become apparent to you what is going wrong here. – Sean Middleditch Dec 28 '12 at 8:41

"position" probably refers to the upper left corner of your entity.

if (x < tileBounds.Right)
position.X = tileBounds.Right;


The above will move the entity's left edge to the colliding tile's right edge. That's good.

if (x > tileBounds.Left)
position.X = tileBounds.Left;


However, this will move the entity's left edge to the colliding tile's left edge. That's bad - it places your entity squarely inside the collidee.

Your top and left checks need to take into account the width and height of your entity.

• Thank you. I fixed the code and edited my question with what I did, but it behaves exactly the same way... so I'm not sure I understand what you're saying. Position is a vector, that looks like this: public static Vector2 position = new Vector2(43.0f, 79.0f); – Fiona Dec 25 '12 at 3:14
• @Fiona It would be a good idea to use e.g. a const variable to give a name to your magic width and height numbers, especially since you will need to use them in more than one place to fix this problem: you have the right idea for the response, but the detection test also needs to be edited similarly. Hint: "if ((x + 5) > tileBounds.Left)" ... – Neverender Dec 25 '12 at 3:28
• OK, I did this and the same problem still occurs. I'll update the post with what I have now. – Fiona Dec 25 '12 at 3:46
• Can anybody please help me? I am really stuck, and don't know how to fix this. – Fiona Dec 27 '12 at 1:57
• Your parentheses are unbalanced, and you incorporated the height into the bottom check, not the top check. Additionally the comparison operators are reversed on your top and bottom checks. Also, I was only assuming that your "position" origin is the top-left of the entity; it's up to you to verify that is the case. I strongly recommend sitting down with a piece of graph paper and a pencil and stepping through your code in your head. – Neverender Dec 28 '12 at 4:59

If Your tile width is less than sprite width, then both conditions

if ((x + spriteWidth) > tileBounds.Left)


and

if (x < tileBounds.Right)


might be met at the same time.

Since You're not using "else if" in Your conditions this will lead to setting position.X twice, and since the second condition is setting it to the right edge, finally it will be just that.

I'm not saying that You should do "else if" as this won't actually solve the real problem. You need to consider this scenario what to do when Your tile rectangle is completely contained within sprite rectangle. The decision is up to You how to handle this.