public Enemy(GraphicsDevice graphicsDevice, EnvironmentBlock[] walls) { // Set enemy speed depending on game difficulty if (LittleTiggy.gameDifficulty == GameDifficulty.Easy) { this.charSpeed = 0.000004F; } else if (LittleTiggy.gameDifficulty == GameDifficulty.Medium) { this.charSpeed = 0.000006F; } else // Hard { this.charSpeed = 0.00001F; } this.enemyPathfinder = new Pathfinder(graphicsDevice); BackgroundPathfinderWorker_Initialise(); if (characterSheetTexture == null) { using (var stream = TitleContainer.OpenStream("Content/CharacterSheet.png")) { characterSheetTexture = Texture2D.FromStream(graphicsDevice, stream); } } // define animation frames walkDown = new Animation(); walkDown.AddFrame(new Rectangle(0, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkDown.AddFrame(new Rectangle(16, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkDown.AddFrame(new Rectangle(0, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkDown.AddFrame(new Rectangle(32, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkLeft = new Animation(); walkLeft.AddFrame(new Rectangle(48, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkLeft.AddFrame(new Rectangle(64, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkLeft.AddFrame(new Rectangle(48, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkLeft.AddFrame(new Rectangle(80, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkRight = new Animation(); walkRight.AddFrame(new Rectangle(96, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkRight.AddFrame(new Rectangle(112, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkRight.AddFrame(new Rectangle(96, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkRight.AddFrame(new Rectangle(128, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkUp = new Animation(); walkUp.AddFrame(new Rectangle(144, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkUp.AddFrame(new Rectangle(160, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkUp.AddFrame(new Rectangle(144, 16, 16, 16), TimeSpan.FromSeconds(.25)); walkUp.AddFrame(new Rectangle(176, 16, 16, 16), TimeSpan.FromSeconds(.25)); Idle = new Animation(); Idle.AddFrame(new Rectangle(0, 16, 16, 16), TimeSpan.FromSeconds(.25)); standDown = new Animation(); standDown.AddFrame(new Rectangle(0, 16, 16, 16), TimeSpan.FromSeconds(.25)); standLeft = new Animation(); standLeft.AddFrame(new Rectangle(48, 16, 16, 16), TimeSpan.FromSeconds(.25)); standRight = new Animation(); standRight.AddFrame(new Rectangle(96, 16, 16, 16), TimeSpan.FromSeconds(.25)); standUp = new Animation(); standUp.AddFrame(new Rectangle(144, 16, 16, 16), TimeSpan.FromSeconds(.25)); currentAnimation = Idle; do // Spawn enemy in grid aligned random position on map where no walls exist. { this.X = (float)randomNumber.Next(128, GameConstants.gameWidth - GameConstants.tileSize); // Don't allow enemy to spawn too close to the player start position. this.Y = randomNumber.Next(128, GameConstants.gameHeight - GameConstants.tileSize); this.X -= this.X % 16; this.Y -= this.Y % 16; } while (IsEnvironmentCollision(walls)); }
void AvoidPlayer(EnvironmentBlock[] walls) { if (isFollowingPath) { // Check if the destination set to the next grid tile by the path is reached. if (Math.Floor(vectorDestinationPosition.X) == Math.Floor(this.X) && Math.Floor(vectorDestinationPosition.Y) == Math.Floor(this.Y)) { isFollowingPath = false; } // Move enemy closer to destination at normal speed if it's more than 1 unit away. if (Math.Floor(vectorDestinationPosition.X) - Math.Floor(this.X) > 1) { this.X += (charSpeed * ticksSinceLastUpdate); currentAnimation = walkRight; } else if (Math.Floor(vectorDestinationPosition.X) - Math.Floor(this.X) < -1) { this.X -= (charSpeed * ticksSinceLastUpdate); currentAnimation = walkLeft; } else if (Math.Floor(vectorDestinationPosition.Y) - Math.Floor(this.Y) > 1) { this.Y += (charSpeed * ticksSinceLastUpdate); currentAnimation = walkDown; } else if (Math.Floor(vectorDestinationPosition.Y) - Math.Floor(this.Y) < -1) { this.Y -= (charSpeed * ticksSinceLastUpdate); currentAnimation = walkUp; } // Move enemy closer to destination just a little bit if it's just one unit away. else if (Math.Floor(vectorDestinationPosition.X) - Math.Floor(this.X) == 1) { this.X += 1; } else if (Math.Floor(vectorDestinationPosition.X) - Math.Floor(this.X) == -1) { this.X -= 1; } else if (Math.Floor(vectorDestinationPosition.Y) - Math.Floor(this.Y) == 1) { this.Y += 1; } else if (Math.Floor(vectorDestinationPosition.Y) - Math.Floor(this.Y) == -1) { this.Y -= 1; } } else { // Refresh the path to follow periodically if (pathfindingTimer.CompareTo(DateTime.Now) < 0 && !BackgroundPathfinderWorker.IsBusy) { pathfindingTimer = DateTime.Now; pathfindingTimer = pathfindingTimer.AddSeconds(pathfindingLongTimerIntervalSeconds); float randomGridAlignedX; float randomGridAlignedY; do { randomGridAlignedX = randomNumber.Next(0, 512); randomGridAlignedY = randomNumber.Next(0, 512); randomGridAlignedX -= randomGridAlignedX % 16; randomGridAlignedY -= randomGridAlignedY % 16; } while (IsEnvironmentCollision(walls, new Vector2(randomGridAlignedX, randomGridAlignedY))); enemyPathfinder.from = new Vector2(this.X - this.X % 16, this.Y - this.Y % 16); enemyPathfinder.destination = new Vector2(randomGridAlignedX, randomGridAlignedY); enemyPathfinder.walls = walls; BackgroundPathfinderWorker.RunWorkerAsync(); } if (pathToFollow != null && !(pathToFollow.Count == 0)) // If we have a path to follow, set the next position in the path as our immediate destination { vectorDestinationPosition = pathToFollow[pathToFollow.Count - 1]; pathToFollow.RemoveAt(pathToFollow.Count - 1); isFollowingPath = true; } else { isFollowingPath = false; } } }