Time for action - staying in bounds

  1. Create a region called "Movement Limitations" in the Player class:
    #region Movement Limitations
    #endregion
    
  2. Inside the Movement Limitations region, add the clampToWorld() method:
    private static void clampToWorld()
    {
    float currentX = BaseSprite.WorldLocation.X;
    float currentY = BaseSprite.WorldLocation.Y;
    currentX = MathHelper.Clamp(
    currentX,
    0,
    Camera.WorldRectangle.Right - BaseSprite.FrameWidth);
    currentY = MathHelper.Clamp(
    currentY,
    0,
    Camera.WorldRectangle.Bottom - BaseSprite.FrameHeight);
    BaseSprite.WorldLocation = new Vector2(currentX, currentY);
    }
    
  3. Add a declaration to the Player class to define the area in which the camera should attempt to keep the player:
    private static Rectangle scrollArea =
    new Rectangle(150, 100, 500, 400);
    
  4. Add the repositionCamera() helper method to the Movement Limitations region of the Player class:
    private static void repositionCamera(
    GameTime gameTime,
    Vector2 moveAngle)
    {
    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
    float moveScale = playerSpeed * elapsed;
    if ((BaseSprite.ScreenRectangle.X < scrollArea.X) &&
    (moveAngle.X < 0))
    {
    Camera.Move(new Vector2(moveAngle.X, 0) * moveScale);
    }
    if ((BaseSprite.ScreenRectangle.Right > scrollArea.Right) &&
    (moveAngle.X > 0))
    {
    Camera.Move(new Vector2(moveAngle.X, 0) * moveScale);
    }
    if ((BaseSprite.ScreenRectangle.Y < scrollArea.Y) &&
    (moveAngle.Y < 0))
    {
    Camera.Move(new Vector2(0, moveAngle.Y) * moveScale);
    }
    if ((BaseSprite.ScreenRectangle.Bottom > scrollArea.Bottom) &&
    (moveAngle.Y > 0))
    {
    Camera.Move(new Vector2(0, moveAngle.Y) * moveScale);
    }
    }
    
  5. Modify the Update() method to call clampToWorld() after the base sprite has been updated. The full Update() method should read:
    public static void Update(GameTime gameTime)
    {
    handleInput(gameTime);
    BaseSprite.Update(gameTime);
    clampToWorld();
    TurretSprite.WorldLocation = BaseSprite.WorldLocation;
    }
    
  6. Still in the handleInput() method, add the following as the last line of the method:
    repositionCamera(gameTime, moveAngle);
    
  7. Launch the game and drive around again. Your tank will stay confined to the game world, but is still able to drive through walls.

What just happened?

Things are looking a little better now. The player can no longer drive off the edge of the world, and when they reach the bottom or right-hand side, the camera will scroll with them. We can still drive through walls, but we are getting there!

When we apply movement to the player, we call clampToWorld(), which separates the player's location into X and Y components. The MathHelper.Clamp() method is then used to ensure that the components stay within the world's coordinate system. The width and height of the sprite is subtracted from the width and height of the game world so that the furthest the player's sprite can get to the right-side and bottom of the world is a full sprite's size away. This will keep the sprite fully within the game world at all times.

When the player approaches an edge of the screen, the camera needs to be adjusted to move in the same direction that the player is moving, assuming that the end of the game world has not yet been reached. By defining the scrollArea rectangle, we are specifying that we would like to keep the player in a 500 by 400 pixel area beginning at (150, 100). This corresponds to the center of our 800 by 600 screen, with a 150 pixel buffer on the left and right edges, and a 100 pixel buffer along the top and bottom.

When repositionCamera() is called, it checks to see if the player has moved out of the defined scrolling area. Each side of the scroll area is checked individually, starting with the left edge. If the X coordinate of the ScreenRectangle is less than the X coordinate of the scrollArea and the player is moving left, the camera is moved left by an amount equal to the amount that the sprite itself will be moved by multiplying the appropriate component of moveAngle by the moveScale value.

The result is that the camera will move the same distance that the player moves. The player's sprite will appear to stay in place while the game world scrolls around it. Since the Camera class limits its own position to ensure that a full view of the world is always displayed, the camera will simply stop moving when the player is close enough to the edge that it can no longer scroll.

Running into tiles

The last limitation we need to account for in player movement is the underlying tile-based map. We want the game to detect when the player is attempting to move into a wall and stop them from doing so.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.234.62