Napoleon
Napoleon

Reputation: 1102

Collision response 2d

Problem: Problem http://img684.imageshack.us/img684/5486/prob1b.png Problem http://img810.imageshack.us/img810/3157/prob3.png Green block is the player and the gray block is the static brick

When jumping up against a tile the player is pushed to the left/right when it stands near the edge of the colliding tile. This probably happens because the jump velocity up is bigger than the x-movement (which may even be 0) and thus the player is corrected over the x-axis...

The pseudo-code goes like this:

{

// Below is some other pseudo-code which should not be part of the problem:

}

Some Code:

  foreach (Stone stone in collidingStones)
            {
                #region Collision Response
                if (DrawRect.Intersects(stone.CollisionRect)) // DrawRect is the players collision rectangle
                {
  //warning bug is in this if-statement. causes the player to be adjusted and go trough neighboar tiles and such
                    Vector2 correction = Collision.CalculateMinimumTranslationDistance(DrawRect, stone.CollisionRect);
                    if (Math.Abs(correction.X) > Math.Abs(correction.Y))
                    {
                        Location += new Vector2(correction.X, 0);
                    }
                    else
                    {
                        Location += new Vector2(0, correction.Y);
                    }

Upvotes: 2

Views: 1196

Answers (1)

Boris B.
Boris B.

Reputation: 5024

Interesting question, I was developing a game in Delphi some years ago and I ran into the same problems. Couple of points:

  • You should correct both X and Y on collision. Correcting only X or Y will look unnatural with high velocities (more than ~3px/update).
  • The kind of collision detection that you are doing would work with rectangularly-filled tiles, but if you had irregular tiles (like a triangle for a slope-section) then it would be impossible to calculate the correction values for collision.

In the end I made an engine in which each tile had the bitmap (the actual visible graphics) and something I called a freemap, which was a black&white bitmap which represented map of free space within a tile. Then I wrote collision functions that operated first in the tile-space (to determine the tiles that collide with the player) then in the bitmap of the tile.

When moving the player you calculate the next point based on the player velocity, and then you test each point along the line between the current position and the calculated next position. If on that line you run into an obstacle then you stop the player at that point.

Upvotes: 0

Related Questions