public static void CheckForCollisions(TileObject tile, out bool pacmanKilled) { pacmanKilled = false; foreach (GhostObject ghost in Ghosts) { if (tile == ghost.CurrentTile) { if (ghost.Status == GhostStatus.Scared) { ghost.Status = GhostStatus.EyesOnly; } else if (ghost.Status != GhostStatus.EyesOnly) { pacmanKilled = true; } } } }
public GhostObject(ContentManager Content, Color color, TileObject startTile, int inBaseTimeLeft) { List <Texture2D> ghostSprites = new List <Texture2D>(); leftEyeTexture = Content.Load <Texture2D>("Sprites\\Ghost\\Eyeball"); rightEyeTexture = Content.Load <Texture2D>("Sprites\\Ghost\\Eyeball"); spriteNormalGhost = Content.Load <Texture2D>("Sprites\\Ghost\\ghost"); spriteBlueGhost = Content.Load <Texture2D>("Sprites\\Ghost\\blue_ghost"); sprite = spriteNormalGhost; this.CurrentTile = startTile; this.Position = this.CurrentTile.Position; this.Status = GhostStatus.InsideBase; this.color = color; this.center = new Vector2(sprite.Height / 2, sprite.Height / 2); this.spriteScale = (float)Globals.GHOST_IMAGE_SIZE / (float)sprite.Height; this.eyeSpriteScale = (float)Globals.GHOST_EYES_IMAGE_SIZE / (float)leftEyeTexture.Height; this.leftEyeOffset.Y = -1 * (float)(sprite.Height * .15) * spriteScale; this.leftEyeOffset.X = -1 * (float)(sprite.Width / 2 * .18) * spriteScale; this.rightEyeOffset.Y = -1 * (float)(sprite.Height * .15) * spriteScale; this.rightEyeOffset.X = (float)(sprite.Width / 2 * .18) * spriteScale; this.eyeCenter = new Vector2(leftEyeTexture.Width / 2, leftEyeTexture.Height / 2); this.eyeRotation = (float)Math.Atan2(0, 1); spriteIndex = 0; spriteTimeElapsed = 0; currentDirection = MovementDirection.Up; distanceTraveled = 0.0f; this.inbaseTimeLeft = inBaseTimeLeft; ai = new GhostAI(this); }
public static void LoadContent(ContentManager Content) { // Initialize Tile and Collision Grid TileGrid = new TileObject[Globals.MAP_NUM_OF_VERTICAL_TILES, Globals.MAP_NUM_OF_HORIZONTAL_TILES]; // Read ASCII map. Populate Tile and Collision grid TextReader reader = new StreamReader("map.txt", Encoding.ASCII); string inputString = reader.ReadToEnd().Replace("\r", "").Replace("\n", ""); char input; int count = 0; for (int row = 0; row < Globals.MAP_NUM_OF_VERTICAL_TILES; row++) { for (int col = 0; col < Globals.MAP_NUM_OF_HORIZONTAL_TILES; col++) { input = inputString[count++]; TileGrid[row, col] = new TileObject(Content, TileGrid, row, col, input); } } HealTile = GetTile('H'); }
public static bool DirectionAllowed(TileObject CurrentTile, MovementDirection direction) { return(DirectionAllowed(CurrentTile, direction, false)); }
internal static TileObject UpdateCurrentTile(Vector2 Position, Vector2 Center, TileObject CurrentTile) { float diffx = CurrentTile.Position.X - Position.X; float diffy = CurrentTile.Position.Y - Position.Y; if (diffx > (float)Globals.MAP_TILE_PIXEL_SIZE / 2.0f) { CurrentTile = CurrentTile.TileLeft; } else if (diffx < -1.0f * (float)Globals.MAP_TILE_PIXEL_SIZE / 2.0f) { CurrentTile = CurrentTile.TileRight; } else if (diffy > (float)Globals.MAP_TILE_PIXEL_SIZE / 2.0f) { CurrentTile = CurrentTile.TileUp; } else if (diffy < -1.0f * (float)Globals.MAP_TILE_PIXEL_SIZE / 2.0f) { CurrentTile = CurrentTile.TileDown; } return(CurrentTile); }
public void Update(GameTime gameTime) { if (Status == GhostStatus.InsideBase) { inbaseTimeLeft -= gameTime.ElapsedGameTime.Milliseconds; if (inbaseTimeLeft <= 0) { Status = GhostStatus.LeavingBase; } } if (Status == GhostStatus.Scared) { statusTimeLeft -= gameTime.ElapsedGameTime.Milliseconds; if (statusTimeLeft <= 0) { Status = (inbaseTimeLeft > 0 ? GhostStatus.InsideBase : GhostStatus.Chase); } } else if (Status == GhostStatus.EyesOnly) { if (CurrentTile == MapObject.HealTile) { Status = GhostStatus.LeavingBase; currentDirection = MovementDirection.Up; futureDirection = MovementDirection.Up; } } else if (Status == GhostStatus.LeavingBase && CurrentTile.IsGate) { Status = GhostStatus.Chase; currentDirection = MovementDirection.Up; futureDirection = MovementDirection.Up; } // Does ghost have the "opportunity" to change direction (He needs to have travelled a full tile) if ((distanceTraveled >= Globals.MAP_TILE_PIXEL_SIZE || distanceTraveled == 0.0f) && Status != GhostStatus.InsideBase) { distanceTraveled %= Globals.MAP_TILE_PIXEL_SIZE; // Change ghosts direction if he's allowed to go that way if (MapObject.DirectionAllowed(CurrentTile, futureDirection, Status == GhostStatus.LeavingBase || Status == GhostStatus.EyesOnly)) { ChangeDirection(futureDirection); } // See if ghost is running into a wall, stop him if he is. if (!MapObject.DirectionAllowed(CurrentTile, currentDirection, Status == GhostStatus.LeavingBase || Status == GhostStatus.EyesOnly)) { currentSpeed = 0.0f; } futureDirection = ai.GetFutureDirection(); } switch (currentDirection) { case MovementDirection.Up: Position.Y = Position.Y - currentSpeed; break; case MovementDirection.Down: Position.Y = Position.Y + currentSpeed; break; case MovementDirection.Left: Position.X = Position.X - currentSpeed; break; case MovementDirection.Right: Position.X = Position.X + currentSpeed; break; } distanceTraveled += currentSpeed; // Update current tile that ghost is in CurrentTile = MapObject.UpdateCurrentTile(Position, center, CurrentTile); }
public MovementDirection GetFutureDirection() { // First determine the target tile that the ghosts are trying to get to, based on a number of factors: if (ghost.Status == GhostStatus.EyesOnly) { // Ghost has been eaten, and needs to head back to base, to the "heal spot". targetPosition = MapObject.HealTile.Position; } else if (ghost.Status == GhostStatus.Scared) { // Ghosts are scared. Generate a random tile and head to there. targetPosition = MapObject.TileGrid[random.Next(0, Globals.MAP_NUM_OF_VERTICAL_TILES - 1), random.Next(0, Globals.MAP_NUM_OF_HORIZONTAL_TILES - 1)].Position; } else if (ghost.Status == GhostStatus.LeavingBase) { // Time to leave the base, just go north. The status will change once you pass the gate. targetPosition = MapObject.TileGrid[0, Globals.MAP_NUM_OF_HORIZONTAL_TILES / 2].Position; } else { // Ghosts are chasing if (ghost.color == Color.Red) // Red chases pacman { targetPosition = PacmanObject.CurrentTile.Position; } else if (ghost.color == Color.Pink) // Pink chases 4 tiles ahead of pacman { targetPosition = PacmanObject.CurrentTile.Position; targetPosition.Y -= (PacmanObject.currentDirection == MovementDirection.Up ? Globals.MAP_TILE_PIXEL_SIZE * 4 : 0.0f); targetPosition.Y += (PacmanObject.currentDirection == MovementDirection.Down ? Globals.MAP_TILE_PIXEL_SIZE * 4 : 0.0f); targetPosition.X -= (PacmanObject.currentDirection == MovementDirection.Left ? Globals.MAP_TILE_PIXEL_SIZE * 4 : 0.0f); targetPosition.X += (PacmanObject.currentDirection == MovementDirection.Right ? Globals.MAP_TILE_PIXEL_SIZE * 4 : 0.0f); } else if (ghost.color == Color.Cyan) // Get point 2 tiles in front of pacman. Then get red ghost position. //Draw line from red ghost to pos in front of pacman and mirror it out across to the other side to find targetTile. { // Get 2 tiles in front of pacman targetPosition = PacmanObject.CurrentTile.Position; targetPosition.Y -= (PacmanObject.currentDirection == MovementDirection.Up ? Globals.MAP_TILE_PIXEL_SIZE * 2 : 0.0f); targetPosition.Y += (PacmanObject.currentDirection == MovementDirection.Down ? Globals.MAP_TILE_PIXEL_SIZE * 2 : 0.0f); targetPosition.X -= (PacmanObject.currentDirection == MovementDirection.Left ? Globals.MAP_TILE_PIXEL_SIZE * 2 : 0.0f); targetPosition.X += (PacmanObject.currentDirection == MovementDirection.Right ? Globals.MAP_TILE_PIXEL_SIZE * 2 : 0.0f); // Mirror out distance from red ghost to position above targetPosition.Y += targetPosition.Y - GhostManager.Ghosts[0].Position.Y; targetPosition.X += targetPosition.X - GhostManager.Ghosts[0].Position.X; } else if (ghost.color == Color.Orange) // Orange chases pacman if 7.5xTILE_SIZE distance from pacman, otherwise, chases scatter point { if (Helpers.GetDistanceBetween(ghost.Position, PacmanObject.Position) >= 7.5f * Globals.MAP_TILE_PIXEL_SIZE) { targetPosition = PacmanObject.CurrentTile.Position; } else { targetPosition = Globals.SCATTER_PT_ORANGE; } } } // Look at the future tile based on the ghosts future direction TileObject futureTile = ghost.CurrentTile.GetFutureTile(ghost.futureDirection); // Consider all tiles surrounding the futureTile that ARE NOT a wall. Also, make sure you don't // end up reversing direction. Calculate the distance target position from each. float upDistance = float.MaxValue, leftDistance = float.MaxValue, downDistance = float.MaxValue, rightDistance = float.MaxValue; if (!futureTile.TileUp.IsWall && ghost.currentDirection != MovementDirection.Down && (ghost.Status == GhostStatus.LeavingBase || ghost.Status == GhostStatus.EyesOnly ? true : !futureTile.TileUp.IsGate)) { upDistance = Helpers.GetDistanceBetween(futureTile.TileUp.Position, targetPosition); } if (!futureTile.TileLeft.IsWall && ghost.currentDirection != MovementDirection.Right && (ghost.Status == GhostStatus.LeavingBase || ghost.Status == GhostStatus.EyesOnly ? true : !futureTile.TileLeft.IsGate)) { leftDistance = Helpers.GetDistanceBetween(futureTile.TileLeft.Position, targetPosition); } if (!futureTile.TileDown.IsWall && ghost.currentDirection != MovementDirection.Up && (ghost.Status == GhostStatus.LeavingBase || ghost.Status == GhostStatus.EyesOnly ? true : !futureTile.TileDown.IsGate)) { downDistance = Helpers.GetDistanceBetween(futureTile.TileDown.Position, targetPosition); } if (!futureTile.TileRight.IsWall && ghost.currentDirection != MovementDirection.Left && (ghost.Status == GhostStatus.LeavingBase || ghost.Status == GhostStatus.EyesOnly ? true : !futureTile.TileRight.IsGate)) { rightDistance = Helpers.GetDistanceBetween(futureTile.TileRight.Position, targetPosition); } // Move in the direction closest to pacman. if (upDistance <= leftDistance && upDistance <= downDistance && upDistance <= rightDistance) { return(MovementDirection.Up); } else if (leftDistance <= downDistance && leftDistance <= rightDistance) { return(MovementDirection.Left); } else if (downDistance <= rightDistance) { return(MovementDirection.Down); } else { return(MovementDirection.Right); } }