435 lines
21 KiB
C#
435 lines
21 KiB
C#
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<List<Rectangle>> CommonTextureSourceRectangles { get; set; }
|
|
public List<Rectangle> AfraidTextureSourceRectangles { get; set; } = new List<Rectangle>();
|
|
public List<List<Rectangle>> DeathTextureSourceRectangles { get; set; } = new List<List<Rectangle>>();
|
|
public double Scale { get; set; }
|
|
public string GhostName { get; set; }
|
|
public Vector2 StartPosition { get; set; }
|
|
public Vector2 AfraidFinishPosition { get; set; }
|
|
public List<DirectionsEnum> 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<DirectionsEnum>();
|
|
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<List<Rectangle>>();
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
CommonTextureSourceRectangles.Add(new List<Rectangle>());
|
|
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<Rectangle>());
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|