#region Movement Limitations #endregion
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); }
private static Rectangle scrollArea = new Rectangle(150, 100, 500, 400);
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); } }
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; }
handleInput()
method, add the following as the last line of the method:repositionCamera(gameTime, moveAngle);
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.
18.191.234.62