Skip to main content
Improved it
Source Link
bobobobo
  • 17.2k
  • 10
  • 67
  • 99

Edit

I have improved it

TheIt seems the key thing I changed is to deal with your AABB's in terms of Left and Right, and stop thinking about X and Yclassifying the intersections.

collision working Intersections are either:

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

  • Ceiling bumps
  • Ground hits (push out of the floor)
  • Mid-air wall collisions
  • Grounded wall collisions

and I broke it down into 4 intersection cases: (p=player, t=some other tile/object)resolve them in that order

4 cases Define a ground collision as player being at least 1/4 way on the tile

So in case 1, for example, pthis is falling down onto ta ground collision and the player (landing, or case of rising floorblue). In case 2, p has hit t will sit on top of the tile (the ceilingblack) with his head. ground collision

In case 1, I will pushBut this is NOT a ground collision and the player up. In case 3, I will push"slip" on the player left. In all cases, only pushright side of the player exactly enough so thattile when he and the object are no longer overlapping.

The meat oflands on it is here, where we check for: not gonig to be a ground collision player will slip by

  1. The depth (or encroachment) of pixel overlap in x and y (encrX, encrY) between the 2 tiles

  2. The number of pixels overlapped in x and y (numPxOverlapX, numPxOverlapY)

See this link forBy this method the code (XNA 4.0) (copy and paste into VS 2010).player will no longer get caught on the sides of walls

  • This code may break down if objects are moving too fast.

The key is to deal with your AABB's in terms of Left and Right, and stop thinking about X and Y.

collision working

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

I broke it down into 4 intersection cases: (p=player, t=some other tile/object)

4 cases

So in case 1, for example, p is falling down onto t (landing, or case of rising floor). In case 2, p has hit t (the ceiling) with his head.

In case 1, I will push the player up. In case 3, I will push the player left. In all cases, only push the player exactly enough so that he and the object are no longer overlapping.

The meat of it is here, where we check for:

  1. The depth (or encroachment) of pixel overlap in x and y (encrX, encrY) between the 2 tiles

  2. The number of pixels overlapped in x and y (numPxOverlapX, numPxOverlapY)

See this link for the code (XNA 4.0) (copy and paste into VS 2010).

  • This code may break down if objects are moving too fast.

Edit

I have improved it

It seems the key thing I changed is classifying the intersections.

Intersections are either:

  • Ceiling bumps
  • Ground hits (push out of the floor)
  • Mid-air wall collisions
  • Grounded wall collisions

and I resolve them in that order

Define a ground collision as player being at least 1/4 way on the tile

So this is a ground collision and the player (blue) will sit on top of the tile (black) ground collision

But this is NOT a ground collision and the player will "slip" on the right side of the tile when he lands on it not gonig to be a ground collision player will slip by

By this method the player will no longer get caught on the sides of walls

deleted 2205 characters in body
Source Link
bobobobo
  • 17.2k
  • 10
  • 67
  • 99

collision working

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

Here isSee this link for the code:

if( p.aabb.Intersects( t.aabb ) ) // intersecting { //compute encroachment in x and y float encrX = 0, encrY = 0 ; // 1: player hit the floor with his feet if( p.Bottom < t.Bottom && // player is above the tile and p.Bottom >= t.Top ) // player's bottom has gotten bigger than tile's top { encrY = t.Top - p.Bottom ; // player must move UP: -y } else if( p.Top > t.Top && // player is below the tile and p.Top <= t.Bottom ) // player's top has entered bottom of the tile { // 2. player's head hit a ceiling tile encrY = t.Bottom - p.Top ; // player needs to move a +y value } // x if( p.Left < t.Left && // p approaches from left and p.Right >= t.Left ) // p's right is stepping on t's left { // 3. p enters t from the left encrX = t.Left - p.Right ; // -x } else if( p.Right > t.Right && // p approaches from right and p.Left <= t.Right ) // p's left is { // 4. p comes from the left encrX = t.Right - p.Left ; // +x } // now who gets pushed back, x or y? // it should be the one with the greatest amount of overlap. float numPxOverlapX = 0, numPxOverlapY = 0; // the number of pixels overlapping in x is if( p.Left < t.Left ) // p is left of t numPxOverlapX = p.Right - t.Left; else // if( p.Right > t.Right ) // p is right of t numPxOverlapX = t.Right - p.Left; if( p.Top < t.Top ) numPxOverlapY = p.Bottom - t.Top ; else //if( p.Bottom > t.Bottom ) numPxOverlapY = t.Bottom - p.Top ; // push back where there is THE MOST // pixel overlap if( numPxOverlapX > numPxOverlapY ) { // lots of horizontal pixel overlap, push back on y p.Pos += new Vector2( 0, encrY ); // no downward motion then if( p.vel.Y > 0 ) p.vel.Y = 0 ; } else { p.Pos += new Vector2( encrX, 0 ) ; } } 

Intersection

I've put up a working XNA (XNA 4.0 project here) (copy and paste into VS 2010).

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

Here is the code:

if( p.aabb.Intersects( t.aabb ) ) // intersecting { //compute encroachment in x and y float encrX = 0, encrY = 0 ; // 1: player hit the floor with his feet if( p.Bottom < t.Bottom && // player is above the tile and p.Bottom >= t.Top ) // player's bottom has gotten bigger than tile's top { encrY = t.Top - p.Bottom ; // player must move UP: -y } else if( p.Top > t.Top && // player is below the tile and p.Top <= t.Bottom ) // player's top has entered bottom of the tile { // 2. player's head hit a ceiling tile encrY = t.Bottom - p.Top ; // player needs to move a +y value } // x if( p.Left < t.Left && // p approaches from left and p.Right >= t.Left ) // p's right is stepping on t's left { // 3. p enters t from the left encrX = t.Left - p.Right ; // -x } else if( p.Right > t.Right && // p approaches from right and p.Left <= t.Right ) // p's left is { // 4. p comes from the left encrX = t.Right - p.Left ; // +x } // now who gets pushed back, x or y? // it should be the one with the greatest amount of overlap. float numPxOverlapX = 0, numPxOverlapY = 0; // the number of pixels overlapping in x is if( p.Left < t.Left ) // p is left of t numPxOverlapX = p.Right - t.Left; else // if( p.Right > t.Right ) // p is right of t numPxOverlapX = t.Right - p.Left; if( p.Top < t.Top ) numPxOverlapY = p.Bottom - t.Top ; else //if( p.Bottom > t.Bottom ) numPxOverlapY = t.Bottom - p.Top ; // push back where there is THE MOST // pixel overlap if( numPxOverlapX > numPxOverlapY ) { // lots of horizontal pixel overlap, push back on y p.Pos += new Vector2( 0, encrY ); // no downward motion then if( p.vel.Y > 0 ) p.vel.Y = 0 ; } else { p.Pos += new Vector2( encrX, 0 ) ; } } 

Intersection

I've put up a working XNA 4.0 project here (copy and paste into VS 2010).

collision working

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

See this link for the code (XNA 4.0) (copy and paste into VS 2010).

Source Link
bobobobo
  • 17.2k
  • 10
  • 67
  • 99

The key is to deal with your AABB's in terms of Left and Right, and stop thinking about X and Y.

You want to "push" only in the direction to allieviate the greatest number of pixel overlap (ie cancel it out by pushing the player back.

I broke it down into 4 intersection cases: (p=player, t=some other tile/object)

4 cases

So in case 1, for example, p is falling down onto t (landing, or case of rising floor). In case 2, p has hit t (the ceiling) with his head.

In case 1, I will push the player up. In case 3, I will push the player left. In all cases, only push the player exactly enough so that he and the object are no longer overlapping.

The meat of it is here, where we check for:

  1. The depth (or encroachment) of pixel overlap in x and y (encrX, encrY) between the 2 tiles

  2. The number of pixels overlapped in x and y (numPxOverlapX, numPxOverlapY)

Here is the code:

if( p.aabb.Intersects( t.aabb ) ) // intersecting { //compute encroachment in x and y float encrX = 0, encrY = 0 ; // 1: player hit the floor with his feet if( p.Bottom < t.Bottom && // player is above the tile and p.Bottom >= t.Top ) // player's bottom has gotten bigger than tile's top { encrY = t.Top - p.Bottom ; // player must move UP: -y } else if( p.Top > t.Top && // player is below the tile and p.Top <= t.Bottom ) // player's top has entered bottom of the tile { // 2. player's head hit a ceiling tile encrY = t.Bottom - p.Top ; // player needs to move a +y value } // x if( p.Left < t.Left && // p approaches from left and p.Right >= t.Left ) // p's right is stepping on t's left { // 3. p enters t from the left encrX = t.Left - p.Right ; // -x } else if( p.Right > t.Right && // p approaches from right and p.Left <= t.Right ) // p's left is { // 4. p comes from the left encrX = t.Right - p.Left ; // +x } // now who gets pushed back, x or y? // it should be the one with the greatest amount of overlap. float numPxOverlapX = 0, numPxOverlapY = 0; // the number of pixels overlapping in x is if( p.Left < t.Left ) // p is left of t numPxOverlapX = p.Right - t.Left; else // if( p.Right > t.Right ) // p is right of t numPxOverlapX = t.Right - p.Left; if( p.Top < t.Top ) numPxOverlapY = p.Bottom - t.Top ; else //if( p.Bottom > t.Bottom ) numPxOverlapY = t.Bottom - p.Top ; // push back where there is THE MOST // pixel overlap if( numPxOverlapX > numPxOverlapY ) { // lots of horizontal pixel overlap, push back on y p.Pos += new Vector2( 0, encrY ); // no downward motion then if( p.vel.Y > 0 ) p.vel.Y = 0 ; } else { p.Pos += new Vector2( encrX, 0 ) ; } } 

Intersection

I've put up a working XNA 4.0 project here (copy and paste into VS 2010).

  • This code may break down if objects are moving too fast.