0
\$\begingroup\$

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.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Commented Dec 28, 2012 at 8:41

2 Answers 2

1
\$\begingroup\$

"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.

\$\endgroup\$
5
  • \$\begingroup\$ 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); \$\endgroup\$ Commented Dec 25, 2012 at 3:14
  • \$\begingroup\$ @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)" ... \$\endgroup\$ Commented Dec 25, 2012 at 3:28
  • \$\begingroup\$ OK, I did this and the same problem still occurs. I'll update the post with what I have now. \$\endgroup\$ Commented Dec 25, 2012 at 3:46
  • \$\begingroup\$ Can anybody please help me? I am really stuck, and don't know how to fix this. \$\endgroup\$ Commented Dec 27, 2012 at 1:57
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Dec 28, 2012 at 4:59
1
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.