Share via


Platformer Move Left Glitch Fix

I have been trying out code samples on Windows Phone. The platformer game sample moves a player left and right by tilting the phone in the direction to travel. The sample code as published on 10/4/2011 has a problem where the player gets stuck when you tilt to move left until you tilt a lot and he flys over left. This happens because the collision code detects a collision with the ground tile at low speeds. Here is my update for the HandleCollisions() method which avoids the problem.

  /// <summary>
 /// Detects and resolves all collisions between the player and his neighboring
 /// tiles. When a collision is detected, the player is pushed away along one
 /// axis to prevent overlapping. There is some special logic for the Y axis to
 /// handle platforms which behave differently depending on direction of movement.
 /// </summary>
 private void HandleCollisions()
 {
 // Get the player's bounding rectangle and find neighboring tiles.
 Rectangle bounds = BoundingRectangle;
 int leftTile = (int)Math.Floor((float)bounds.Left / Tile.Width);
 int rightTile = (int)Math.Ceiling(((float)bounds.Right / Tile.Width)) - 1;
 int topTile = (int)Math.Floor((float)bounds.Top / Tile.Height);
 int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / Tile.Height)) - 1;
 
 // Reset flag to search for ground collision.
 isOnGround = false;
 
 // For each potentially colliding tile,
 for (int y = topTile; y <= bottomTile; ++y)
 {
 //
 // The y loop checks all tile rows that the player intersects with from top to bottom. The x loop checks
 // each tile that the player intersects with on that row depending on the players direction of travel.
 // The collision tests are required to go in the direction of travel so as to avoid detecting collisions
 // with the platform that the player is running on in the horizontal direction. Instead a ground
 // collision will be detected and corrected first in the vertical direction and since the player position
 // is moved back up and is no longer in line with the platform when the horizontal collision check occurs.
 // This direction of travel identification is only required because the collision correction assumes that
 // the axis to bounce the player back is the axis with the smallest overlap. This isn't always 100% true.
 //
 if (velocity.X < 0)
 for (int x = rightTile; x >= leftTile; --x)
 HandleTileCollisions(ref bounds, x, y);
 else
 for (int x = leftTile; x <= rightTile; ++x)
 HandleTileCollisions(ref bounds, x, y);
 }
 
 // Save the new bounds bottom.
 previousBottom = bounds.Bottom;
 }
 
 /// <summary>
 /// Calcualtes and corrects collisions of the player position with items on the level map. This method identifies the depth of the 
 /// collision in the x and y axis and moves the player position back to a location that would not overlap with the object it
 /// collided with. It does this in the axis with the smallest collision as a guess as to the direction the player should bounce
 /// off the object being collided with. This method does a nice job of having common code for collisions regardless of the
 /// direction of travel on the axis as one way is +ve and the other is -ve.
 /// </summary>
 /// <param name="bounds">the bounding rectabgle in pixels for the player sprite as calculated by the GetBoundingRectangle property</param>
 /// <param name="x">the x location of the tile on the map in the range 0 - 19</param>
 /// <param name="y">the y location of the tile on the map in the range 0 - 14</param>
 void HandleTileCollisions(ref Rectangle bounds, int x, int y)
 {
 // put the code in here from within the for loop in the original HandleCollisions() method
 }