0

I am making a small 2D engine and decided to use separating axis theorem for practice. I have the collisions detection and translation working with a player object, but when the playing collides with more than one object it will stop the player's movement. Here is an example of my problem:

The player is moving along the wall pushing himself both down and right. Once the player reaches the intersection between two tiles he can no longer move down because the tile below him detects the collision and will push the player up before the tile directly to his right pushes him to the left. I believe the problem is that the tile below the player is being tested for collision before the other tile, but I don't know how to work around this.

Here is the portion of my code which I believe needs to be changed:

protected override void Update(GameTime gameTime)
    {
        gameCamera.Update(new Vector2(player._boundingBox.X, player._boundingBox.Y));

        foreach (Layer l in currentLevel.Layers)
        {
            foreach (GameObject gameObject in l.layerMapObjects)
            {
                gameObject.Update(gameTime);
            }
        }

        player.Update(gameTime);

        foreach (Layer l in currentLevel.Layers)
        {
            foreach (GameObject gameObject in l.layerMapObjects)
            {
                if (gameObject._isCollidable)
                {
                    Vector2 vectorTranslation = Collision(player._boundingBox, gameObject._boundingBox);
                    player._boundingBox.X += (int)vectorTranslation.X;
                    player._boundingBox.Y += (int)vectorTranslation.Y;
                }
            }
        }

        base.Update(gameTime);
    }

All of my collision right now is between rectangles, and the Collision() function will detect collisions and return the translation needed to move the player if there is one. I hope that someone can help me out with this. Thanks.

1 Answer 1

1

If the problem is that your player is being updated before all the collisions are detected, then try batching the process. That is; instead of applying the vectorTranslations immediately create a list of them, then when all collisions have been detected apply the list of translations to the player.

Sign up to request clarification or add additional context in comments.

2 Comments

I understand what you are saying, and the problem with that is you would still have both translations applied to the player in the end. Going along with the list idea, I made a list off all the objects that were colliding with the player, then I resolved the objects collision that had the least distance from the player. I then iterated through all the remaining objects to see if any were colliding after. If any remaining objects were still colliding, then I would repeated the process until all the collisions were resolved. This seems to work, but if there is an easier way let me know.
Ah, I hadn't considered the case where your tick time was large enough for collisions to be invalidated. Your idea of process the closest, update, then process others seems sensible. It would perhaps have difficulties if you have objects moving at different speeds. You could possibly optimise it by building an ordered queue by time to impact instead of just an unordered list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.