using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.IO; using System.Linq; using System.Diagnostics; using System.Threading; namespace Pacman.Classes { public class Ghost { public int CurrentDirectionTexturesNumber { get; set; } public int CurrentTextureNumber { get; set; } public float Speed = 1.5f; public Vector2 Position { get; set; } public bool IsAfraidEffectOn { get; set; } public int AfraidTime { get; set; } public int AnimationCooldawn { get; set; } public bool IsAlive { get; set; } public string Obstackles { get; set; } public Rectangle GhostRectangle = new Rectangle(); public List> CommonTextureSourceRectangles { get; set; } public List AfraidTextureSourceRectangles { get; set; } = new List(); public List> DeathTextureSourceRectangles { get; set; } = new List>(); public double Scale { get; set; } public string GhostName { get; set; } public Vector2 StartPosition { get; set; } public Vector2 AfraidFinishPosition { get; set; } public List Directions { get; set; } public DirectionsEnum CurrentDirection { get; set; } public PathFinder Finder { get; set; } string[] file = File.ReadAllText("map.txt").Replace("\r", "").Split('\n'); public Ghost(string GhostName) { Finder = new PathFinder(); this.GhostName = GhostName; Point size = new Point(22, 22); Point StartTexturePosition = new Point(); CurrentDirectionTexturesNumber = 0; CurrentTextureNumber = 0; IsAfraidEffectOn = false; AfraidTime = 0; IsAlive = true; Obstackles = "┃━┏┓┗┛!"; Directions = new List(); if (GhostName == "Blinky") { StartTexturePosition = new Point(0, 144); StartPosition = new Vector2(324, 324); AfraidFinishPosition = new Vector2(624, 696); } else if (GhostName == "Pinky") { StartTexturePosition = new Point(0, 192); StartPosition = new Vector2(276, 348); AfraidFinishPosition = new Vector2(48, 696); } else if (GhostName == "Inky") { StartTexturePosition = new Point(192, 192); StartPosition = new Vector2(372, 348); AfraidFinishPosition = new Vector2(624, 48); } else if (GhostName == "Clyde") { StartTexturePosition = new Point(0, 216); StartPosition = new Vector2(324, 348); AfraidFinishPosition = new Vector2(48, 48); } AfraidTextureSourceRectangles.Add(new Rectangle(new Point(192, 96), size)); AfraidTextureSourceRectangles.Add(new Rectangle(new Point(216, 96), size)); Position = StartPosition; GhostRectangle = new Rectangle(0, 0, 24, 24); CommonTextureSourceRectangles = new List>(); for (int i = 0; i < 4; i++) { CommonTextureSourceRectangles.Add(new List()); for (int j = 0; j < 2; j++) { CommonTextureSourceRectangles[i].Add(new Rectangle(new Point(StartTexturePosition.X + 24 * (i * 2 + j), StartTexturePosition.Y), size)); } } StartTexturePosition = new Point(192, 216); for (int i = 0; i < 4; i++) { DeathTextureSourceRectangles.Add(new List()); for (int j = 0; j < 2; j++) { DeathTextureSourceRectangles[i].Add(new Rectangle(new Point(StartTexturePosition.X + 24 * (i * 2 + j), StartTexturePosition.Y), size)); } } } public void Update() { if ((Directions.Count == 0 || CurrentDirection == DirectionsEnum.Stop)) { if (IsAlive && !IsAfraidEffectOn) { Vector2 PersonalPosition = GetPersonalTargetPosition(); Directions = Finder.FindWave((int)Position.X / 24, (int)Position.Y / 24, (int)PersonalPosition.X / 24, (int)PersonalPosition.Y / 24); } else if (!IsAlive) { Directions = Finder.FindWave((int)Position.X / 24, (int)Position.Y / 24, (int)StartPosition.X / 24, (int)StartPosition.Y / 24); } else if (IsAfraidEffectOn) { Directions = Finder.FindWave((int)Position.X/24, (int)Position.Y/24, (int)AfraidFinishPosition.X/24, (int)AfraidFinishPosition.Y/24); } } if ((Position.Y - 12) % 24 == 0 && (Position.X - 12) % 24 == 0 && Directions.Count != 0) { if (Directions[0] == DirectionsEnum.Up && !Obstackles.Contains(file[(int)(Position.Y / 24 - 1)][(int)Position.X / 24])) { CurrentDirection = DirectionsEnum.Up; CurrentDirectionTexturesNumber = 3; Directions.Remove(Directions[0]); } else if (Directions[0] == DirectionsEnum.Right && !Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 + 1)])) { CurrentDirection = DirectionsEnum.Right; CurrentDirectionTexturesNumber = 0; Directions.Remove(Directions[0]); } else if (Directions[0] == DirectionsEnum.Down && !Obstackles.Contains(file[(int)(Position.Y / 24 + 1)][(int)Position.X / 24])) { CurrentDirection = DirectionsEnum.Down; CurrentDirectionTexturesNumber = 1; Directions.Remove(Directions[0]); } else if (Directions[0] == DirectionsEnum.Left && !Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 - 1)])) { CurrentDirection = DirectionsEnum.Left; CurrentDirectionTexturesNumber = 2; Directions.Remove(Directions[0]); } else if (Directions[0] == DirectionsEnum.Stop) { CurrentDirection = DirectionsEnum.Stop; Directions.Remove(Directions[0]); } } if (CurrentDirection == DirectionsEnum.Up && !Obstackles.Contains(file[(int)(Position.Y / 24 - 0.5)][(int)Position.X / 24])) { Position = new Vector2(Position.X, Position.Y - Speed); } else if (CurrentDirection == DirectionsEnum.Right && !Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 + 0.5)])) { Position = new Vector2(Position.X + Speed, Position.Y); } else if (CurrentDirection == DirectionsEnum.Down && !Obstackles.Contains(file[(int)(Position.Y / 24 + 0.5)][(int)Position.X / 24])) { Position = new Vector2(Position.X, Position.Y + Speed); } else if (CurrentDirection == DirectionsEnum.Left && !Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 - 0.5)])) { Position = new Vector2(Position.X - Speed, Position.Y); } if (CurrentDirection == DirectionsEnum.Up && Obstackles.Contains(file[(int)(Position.Y / 24 - 0.5)][(int)Position.X / 24])) { Position = new Vector2(Position.X, ((int)(Position.Y / 24)) * 24 + 12); CurrentDirection = DirectionsEnum.Stop; } else if (CurrentDirection == DirectionsEnum.Right && Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 + 0.5)])) { Position = new Vector2(((int)(Position.X / 24)) * 24 + 12, Position.Y); CurrentDirection = DirectionsEnum.Stop; } else if (CurrentDirection == DirectionsEnum.Down && Obstackles.Contains(file[(int)(Position.Y / 24 + 0.5)][(int)Position.X / 24])) { Position = new Vector2(Position.X, ((int)(Position.Y / 24)) * 24 + 12); CurrentDirection = DirectionsEnum.Stop; } else if (CurrentDirection == DirectionsEnum.Left && Obstackles.Contains(file[(int)Position.Y / 24][(int)(Position.X / 24 - 0.5)])) { Position = new Vector2(((int)(Position.X / 24)) * 24 + 12, Position.Y); CurrentDirection = DirectionsEnum.Stop; } if (CurrentDirection == DirectionsEnum.Left && file[(int)Position.Y / 24][(int)Position.X / 24] == '1') { Position = new Vector2(648, 348); } else if (CurrentDirection == DirectionsEnum.Right && file[(int)Position.Y / 24][(int)Position.X / 24] == '2') { Position = new Vector2(24, 348); } GhostRectangle.X = (int)Position.X; GhostRectangle.Y = (int)Position.Y; if (Position.X/24 == StartPosition.X/24 && Position.Y/24 == StartPosition.Y/24 && !IsAlive) { IsAlive = true; Speed /= 4; } if (AfraidTime == 0 && IsAfraidEffectOn) { IsAfraidEffectOn = false; Directions.Clear(); } else if (AfraidTime != 0 && !IsAfraidEffectOn) { IsAfraidEffectOn = true; Directions.Clear(); } if (AfraidTime != 0) { AfraidTime--; } if (AnimationCooldawn == 6) { CurrentTextureNumber++; AnimationCooldawn = 0; } AnimationCooldawn++; if (CurrentTextureNumber > 1) { CurrentTextureNumber = 0; } if (GhostRectangle.Intersects(Game1.pacman.PacmanRectangle) && !IsAfraidEffectOn && IsAlive) { // Pacman died if (Game1.pacman.ExtraLives > 0) { Thread vibrateThread = new Thread(time => { int vibrationTime = (int)time; GamePad.SetVibration(0, 1, 1); Thread.Sleep(vibrationTime); GamePad.SetVibration(0, 0, 0); }); vibrateThread.Start(400); Game1.deathSong.Play(); Game1.RestartGame(false); } else { Thread vibrateThread = new Thread(time => { int vibrationTime = (int)time; GamePad.SetVibration(0, 1, 1); Thread.Sleep(vibrationTime); GamePad.SetVibration(0, 0, 0); }); vibrateThread.Start(1000); Game1.UpdateHighScore(Game1.pacman.highScore); Game1.gameState = GameState.GameOver; Game1.deathSong.Play(); } } else if (GhostRectangle.Intersects(Game1.pacman.PacmanRectangle) && IsAfraidEffectOn && IsAlive) { Thread vibrateThread = new Thread(time => { int vibrationTime = (int)time; GamePad.SetVibration(0, 1, 1); Thread.Sleep(vibrationTime); GamePad.SetVibration(0, 0, 0); }); vibrateThread.Start(200); Speed *= 4; Debug.WriteLine(200 * Game1.pacman.ghostsEaten); Game1.pacman.Score += 200 * Game1.pacman.ghostsEaten; Game1.pacman.ghostsEaten++; Game1.ghostDiedSound.Play(); Directions.Clear(); IsAlive = false; } } public void Draw(SpriteBatch spriteBatch) { Scale = 24 / 22; Rectangle CurrentSourceRectangle = new Rectangle(); if (!IsAfraidEffectOn && IsAlive) { CurrentSourceRectangle = CommonTextureSourceRectangles[CurrentDirectionTexturesNumber][CurrentTextureNumber]; } else if (!IsAlive) { CurrentSourceRectangle = DeathTextureSourceRectangles[CurrentDirectionTexturesNumber][CurrentTextureNumber]; } else if (IsAfraidEffectOn) { CurrentSourceRectangle = AfraidTextureSourceRectangles[CurrentTextureNumber]; } spriteBatch.Draw(Game1.spriteSheet, Position, CurrentSourceRectangle, Color.White, 0, new Vector2(11, 11), (float)Scale, SpriteEffects.None, 0); } public Vector2 GetPersonalTargetPosition() { Vector2 TargetPosition = new Vector2(); if (GhostName == "Blinky") { TargetPosition = Game1.pacman.Position; } else if (GhostName == "Clyde") { Vector2 minusVector = Position - Game1.pacman.Position; minusVector = new Vector2(minusVector.X, minusVector.Y) / 24; if (Math.Abs(minusVector.X) <= 4 && Math.Abs(minusVector.Y) <= 4) { for (int i = 0; i < Game1.Ghosts.Count; i++) { if (Game1.Ghosts[i].GhostName == "Pinky") { TargetPosition = Game1.Ghosts[i].Position; } } } else { TargetPosition = Game1.pacman.Position; } } else if (GhostName == "Pinky") { if (Game1.pacman.Position.Y / 24 + 3 <= 29 && Game1.pacman.Position.Y / 24 - 3 >= 1 && Game1.pacman.Position.X / 24 + 3 <= 26 && Game1.pacman.Position.X / 24 - 3 >= 1) { if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 - 2.5)][(int)(Game1.pacman.Position.X / 24 - 2.5)])) { TargetPosition = new Vector2((int)(Game1.pacman.Position.X - 24 * 2.5), (int)(Game1.pacman.Position.Y - 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 + 2.5)][(int)(Game1.pacman.Position.X / 24 + 2.5)])) { TargetPosition = new Vector2((int)(Game1.pacman.Position.X + 24 * 2.5), (int)(Game1.pacman.Position.Y + 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 - 2.5)][(int)(Game1.pacman.Position.X / 24 + 2.5)])) { TargetPosition = new Vector2((int)(Game1.pacman.Position.X + 24 * 2.5), (int)(Game1.pacman.Position.Y - 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 + 2.5)][(int)(Game1.pacman.Position.X / 24 - 2.5)])) { TargetPosition = new Vector2((int)(Game1.pacman.Position.X - 24 * 2.5), (int)(Game1.pacman.Position.Y + 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 + 2.5)][(int)(Game1.pacman.Position.X / 24)]) && Game1.pacman.Direction != "Down") { TargetPosition = new Vector2((int)(Game1.pacman.Position.X), (int)(Game1.pacman.Position.Y + 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24 - 2.5)][(int)(Game1.pacman.Position.X / 24)]) && Game1.pacman.Direction != "Up") { TargetPosition = new Vector2((int)(Game1.pacman.Position.X), (int)(Game1.pacman.Position.Y - 24 * 2.5)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24)][(int)(Game1.pacman.Position.X / 24 + 2.5)]) && Game1.pacman.Direction != "Right") { TargetPosition = new Vector2((int)(Game1.pacman.Position.X + 24 * 2.5), (int)(Game1.pacman.Position.Y)); } else if (!Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 24)][(int)(Game1.pacman.Position.X / 24 - 2.5)]) && Game1.pacman.Direction != "Left") { TargetPosition = new Vector2((int)(Game1.pacman.Position.X - 24 * 2.5), (int)(Game1.pacman.Position.Y)); } } else { TargetPosition = Game1.pacman.Position; } } else if (GhostName == "Inky") { if (Game1.pacman.Position.Y / 24 + 3 <= 29 && Game1.pacman.Position.Y / 24 - 3 >= 1 && Game1.pacman.Position.X / 24 + 3 <= 26 && Game1.pacman.Position.X / 24 - 3 >= 1) { int X = 0; int Y = 0; float i = (float)1.5; if (Game1.pacman.Direction != "Up" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48 + i)][(int)(Game1.pacman.Position.X / 48)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2, Game1.pacman.Position.Y / 2 + i * 24); } else if (Game1.pacman.Direction != "Down" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48 - i)][(int)(Game1.pacman.Position.X / 48)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2, Game1.pacman.Position.Y / 2 - i * 24); } else if (Game1.pacman.Direction != "Left" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48)][(int)(Game1.pacman.Position.X / 48 + i)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2 + i * 24, Game1.pacman.Position.Y / 2); } else if (Game1.pacman.Direction != "Right" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48)][(int)(Game1.pacman.Position.X / 48 - i)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2 - i * 24, Game1.pacman.Position.Y / 2); } else if (Game1.pacman.Direction != "Up" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48 + i + 1)][(int)(Game1.pacman.Position.X / 48)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2, Game1.pacman.Position.Y / 2 + i * 24 + 24); } else if (Game1.pacman.Direction != "Left" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48)][(int)(Game1.pacman.Position.X / 48 + i + 1)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2 + i * 24 + 24, Game1.pacman.Position.Y / 2); } else if (Game1.pacman.Direction != "Down" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48 - i - 1)][(int)(Game1.pacman.Position.X / 48)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2, Game1.pacman.Position.Y / 2 - i * 24 - 24); } else if (Game1.pacman.Direction != "Right" && !Obstackles.Contains(file[(int)(Game1.pacman.Position.Y / 48)][(int)(Game1.pacman.Position.X / 48 - i - 1)])) { TargetPosition = new Vector2(Game1.pacman.Position.X / 2 - i * 24 - 24, Game1.pacman.Position.Y / 2); } else { TargetPosition = Game1.pacman.Position; } } else { if (Game1.pacman.Position.X < 180) { TargetPosition = new Vector2(14 * 24, 26 * 24); } else if (Game1.pacman.Position.X > 408) { TargetPosition = new Vector2(14 * 24, 24); } else { TargetPosition = Game1.pacman.Position; } } } if (TargetPosition == new Vector2(0, 0)) { TargetPosition = Position; } return TargetPosition; } } }