Search code examples
c#xnamonogame

Origin of Rectangle for Collision Detection in MonoGame


I'm having a bit of trouble with 2D collision detection in my game.
The problem is that my player's rectangle does not register an intersection with the rectangles of other objects correctly.

I'm wondering if the origin variable I used to rotate my player has anything to do with my problem and how I can fix it.

I'll explain the problem in more detail, but here is my code first: NOTE: Origin is of type Vector2, angle is of type float, all collision rectangles are of type Rectangle.

//Player.Update method

        //origin needs to be in update, because position of source changes for every frame of animation
        origin = new Vector2(Width / 2, Height / 2);
        playerDirection = new Vector2((float)Math.Sin(angle), (float)Math.Cos(angle));

        //Updating the position of my collision rectangle
        collisionRect.X = (int)position.X;
        collisionRect.Y = (int)position.Y;

        //Changing the values of angle while key is pressed
        if (Keyboard.GetState().IsKeyDown(Keys.A))
        {
            angle -= 0.05f;
        }

        if (Keyboard.GetState().IsKeyDown(Keys.D))
        {
            angle += 0.05f;
        }
        //Updating player's position
        if (Keyboard.GetState().IsKeyUp(Keys.X))
        {
            keyPress = false;
        }

        if (Keyboard.GetState().IsKeyDown(Keys.W))
        {
            position -= playerDirection * Speed;
        }

        if (Keyboard.GetState().IsKeyDown(Keys.S))
            position += playerDirection * Speed;
        //Checking for collision detection with background objects
        if(BackgroundMaker.collisionPositions.Count >= 1)
        {
            foreach(Rectangle colPos in BackgroundMaker.collisionPositions)
            {
                if(collisionRect.Intersects(colPos))
                {
                    if (collisionRect.X < colPos.Right)
                        position.X = colPos.Right;
                }
            }
        }
    }
}

The problem with this code is, my player only collides with the wall when he's halfway through. I haven't implemented collision for right, up and down sides yet, only for the left side.

Here is what it looks like: enter image description here

Thanks in advance for anyone who can help me answer this question. If you need further information, please let me know.


Solution

  • Your code is working how you have instructed

    if (collisionRect.X < colPos.Right)
        position.X = colPos.Right;
    

    Here you are checking, if the middle of the collision box is less than the right side of the object, then set the players middle position to the right of the object, therefore the middle of the player cannot go further than the object it is intersecting.

    However this is not considering the players width

    You need to adapt your code to work more like this:

    float halfWidth = 16.0f; // ideally add a width to the player class and divide by 2
    if (collisionRect.X - halfWidth < colPos.Right)
        position.X = colPos.Right + halfWidth;