private bool WallAt(Point cell, BaseMap map) { if (cell.X >= 0 && cell.Y >= 0 && cell.X < map.Size.X && cell.Y < map.Size.Y) { return(map.CollisionLayer[cell.X, cell.Y]); } else { return(false); } }
public void MovePlayer(BaseMap map, float? customDeltaTime = null) { if (IsAlive) { IsMoving = RealMovePlayer(customDeltaTime); // If the player is moving if (IsMoving) { ComputeWallCollision(map); } if (CurrentDirection != PreviousDirection) { SendPosition(); } // Call Update method of DynamicEntity class base.Update(); PreviousDirection = CurrentDirection; } }
protected void ComputeWallCollision(BaseMap map) { #region Smooth movement // If the player want to go to top... if (CurrentDirection == LookDirection.Up) { // ... and that there is a wall if (WallAt(new Point(CellPosition.X, CellPosition.Y - 1), map)) { // If he is more on the left side, we lag him to the left if (IsMoreLeftSide() && !WallAt(new Point(CellPosition.X - 1, CellPosition.Y - 1), map)) { if (!WallAt(new Point(CellPosition.X - 1, CellPosition.Y), map)) { Position = new Vector2(Position.X - GetMovementSpeed(), Position.Y); } } else if (IsMoreRightSide() && !WallAt(new Point(CellPosition.X + 1, CellPosition.Y - 1), map)) { if (!WallAt(new Point(CellPosition.X + 1, CellPosition.Y), map)) { Position = new Vector2(Position.X + GetMovementSpeed(), Position.Y); } } } // ... and that there is no wall else { // If he is more on the left side if (IsMoreLeftSide()) { Position = new Vector2(Position.X + GetMovementSpeed(), Position.Y); } // If he is more on the right side else if (IsMoreRightSide()) { Position = new Vector2(Position.X - GetMovementSpeed(), Position.Y); } } } // If the player want to go to bottom and that there is a wall else if (CurrentDirection == LookDirection.Down) { // Wall at the bottom ? if (WallAt(new Point(CellPosition.X, CellPosition.Y + 1), map)) { // If he is more on the left side, we lag him to the left if (IsMoreLeftSide() && !WallAt(new Point(CellPosition.X - 1, CellPosition.Y + 1), map)) { if (!WallAt(new Point(CellPosition.X - 1, CellPosition.Y), map)) { Position = new Vector2(Position.X - GetMovementSpeed(), Position.Y); } } else if (IsMoreRightSide() && !WallAt(new Point(CellPosition.X + 1, CellPosition.Y + 1), map)) { if (!WallAt(new Point(CellPosition.X + 1, CellPosition.Y), map)) { Position = new Vector2(Position.X + GetMovementSpeed(), Position.Y); } } } else { // If he is more on the left side if (IsMoreLeftSide()) { Position = new Vector2(Position.X + GetMovementSpeed(), Position.Y); } // If he is more on the right side else if (IsMoreRightSide()) { Position = new Vector2(Position.X - GetMovementSpeed(), Position.Y); } } } // If the player want to go to left and that there is a wall else if (CurrentDirection == LookDirection.Left) { if (WallAt(new Point(CellPosition.X - 1, CellPosition.Y), map)) { // If he is more on the top side, we lag him to the top if (IsMoreTopSide() && !WallAt(new Point(CellPosition.X - 1, CellPosition.Y - 1), map)) { if (!WallAt(new Point(CellPosition.X, CellPosition.Y - 1), map)) { Position = new Vector2(Position.X, Position.Y - GetMovementSpeed()); } } else if (IsMoreBottomSide() && !WallAt(new Point(CellPosition.X - 1, CellPosition.Y + 1), map)) { if (!WallAt(new Point(CellPosition.X, CellPosition.Y + 1), map)) { Position = new Vector2(Position.X, Position.Y + GetMovementSpeed()); } } } else { // If he is more on the top side, we lag him to the bottom if (IsMoreTopSide()) { Position = new Vector2(Position.X, Position.Y + GetMovementSpeed()); } else if (IsMoreBottomSide()) { Position = new Vector2(Position.X, Position.Y - GetMovementSpeed()); } } } // If the player want to go to right and that there is a wall else if (CurrentDirection == LookDirection.Right) { if (WallAt(new Point(CellPosition.X + 1, CellPosition.Y), map)) { // If he is more on the top side, we lag him to the top if (IsMoreTopSide() && !WallAt(new Point(CellPosition.X + 1, CellPosition.Y - 1), map)) { if (!WallAt(new Point(CellPosition.X, CellPosition.Y - 1), map)) { Position = new Vector2(Position.X, Position.Y - GetMovementSpeed()); } } else if (IsMoreBottomSide() && !WallAt(new Point(CellPosition.X + 1, CellPosition.Y + 1), map)) { if (!WallAt(new Point(CellPosition.X, CellPosition.Y + 1), map)) { Position = new Vector2(Position.X, Position.Y + GetMovementSpeed()); } } } else { // If he is more on the top side, we lag him to the top if (IsMoreTopSide()) { Position = new Vector2(Position.X, Position.Y + GetMovementSpeed()); } else if (IsMoreBottomSide()) { Position = new Vector2(Position.X, Position.Y - GetMovementSpeed()); } } } #endregion #region Wall collision // -- Vertical check -- // // Is there a wall on the top ? if (WallAt(new Point(CellPosition.X, CellPosition.Y - 1), map)) { // Is there a wall on the bottom ? if (WallAt(new Point(CellPosition.X, CellPosition.Y + 1), map)) { // Top collision and Bottom collision if ((CurrentDirection == LookDirection.Up && IsMoreTopSide()) || (CurrentDirection == LookDirection.Down && IsMoreBottomSide())) { PositionY = CellPosition.Y * Engine.TileHeight; } } // No wall at the bottom else { // Top collision if (CurrentDirection == LookDirection.Up && IsMoreTopSide()) { PositionY = CellPosition.Y * Engine.TileHeight; } } } // Wall only at the bottom else if (WallAt(new Point(CellPosition.X, CellPosition.Y + 1), map)) { // Bottom collision if (CurrentDirection == LookDirection.Down && IsMoreBottomSide()) { PositionY = CellPosition.Y * Engine.TileHeight; } // To lag him else if (CurrentDirection == LookDirection.Down) { if (IsMoreLeftSide()) { PositionX += GetMovementSpeed(); } else if (IsMoreRightSide()) { PositionX -= GetMovementSpeed(); } } } // -- Horizontal check -- // // Is there a wall on the left ? if (WallAt(new Point(CellPosition.X - 1, CellPosition.Y), map)) { // Is there a wall on the right ? if (WallAt(new Point(CellPosition.X + 1, CellPosition.Y), map)) { // Left and right collisions if ((CurrentDirection == LookDirection.Left && IsMoreLeftSide()) || (CurrentDirection == LookDirection.Right && IsMoreRightSide())) { PositionX = CellPosition.X * Engine.TileWidth - Engine.TileWidth / 2 + Engine.TileWidth / 2; } } // Wall only at the left else { // Left collision if (CurrentDirection == LookDirection.Left && IsMoreLeftSide()) { PositionX = CellPosition.X * Engine.TileWidth - Engine.TileWidth / 2 + Engine.TileWidth / 2; } } } // Wall only at the right else if (WallAt(new Point(CellPosition.X + 1, CellPosition.Y), map)) { // Right collision if (CurrentDirection == LookDirection.Right && IsMoreRightSide()) { PositionX = CellPosition.X * Engine.TileWidth - Engine.TileWidth / 2 + Engine.TileWidth / 2; } } #endregion // The player must stay in the map PositionX = MathHelper.Clamp(Position.X, Engine.TileWidth, (map.Size.X * Engine.TileWidth) - 2 * Engine.TileWidth); PositionY = MathHelper.Clamp(Position.Y, Engine.TileHeight, (map.Size.Y * Engine.TileHeight) - 2 * Engine.TileWidth); }