///////////////////////////////////////////||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ///////////////////////////////////// CONSTRUCTOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ///////////////////////////////////////////||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ //Pre: The game tiles, x and y position fo the enemy, width and height of the enemy, and the width and height of the screen //Post: The enemy is created //Desc: A constructor for the enemy public Enemy(Tile[,] gameTiles, int xPos, int yPos, int enemyWidth, int enemyHeight, int screenWidth, int screenHeight) { //Sets the pathfinding and frame animation objects pathFinding = new PathFinding(gameTiles); frameAnimation = new FrameAnimation(rifle.GetTextures(AnimationState.Idle), IDLE_FRAME_DELAY); //Sets the human to not moving HumanMoving = false; //Sets the position and bounds of the enemy Position = new Vector2(xPos, yPos); bounds = new Rectangle((int)Position.X, (int)Position.Y, enemyWidth, enemyHeight); //Creates a new list of projectiles Projectiles = new List <Projectile>(); //Sets the width and height of the screen this.screenWidth = screenWidth; this.screenHeight = screenHeight; //Sets the health to full Health = 100; }
///////////////////////////////////////////||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /////////////////////////////////////// METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ///////////////////////////////////////////||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ //Pre: The player, the game tiles, and whether the pathfinding needs to be checked //Post: The enemy is updated //Desc: An update method for the enemy public void Update(Player player, Tile[,] gameTiles, bool pathCheck) { //Gets whether the player is currently in view playerInView = IsPlayerInView(player, gameTiles); //If the player is in view and the path needs to be checked for the current enemy at the current frame if (playerInView && pathCheck) { //Clears the current path currentPath.Clear(); //Calculates the row and column of the tile that the enemy and player are on Vector2 enemyLocation = new Vector2((float)Math.Round(Position.X / Tile.TILE_X_SIZE), (float)Math.Round(Position.Y / Tile.TILE_Y_SIZE)); Vector2 playerLocation = player.Position + player.GetWallDisplacement(); playerLocation = new Vector2(playerLocation.X / Tile.TILE_X_SIZE, playerLocation.Y / Tile.TILE_Y_SIZE); //Creates a new pathfinding instance with the gametiles and finds the path pathFinding = new PathFinding(gameTiles); pathFinding.FindPath(new Node((int)enemyLocation.X, (int)enemyLocation.Y), new Node((int)playerLocation.X, (int)playerLocation.Y)); //Temporary list of nodes which is used to get the enemy's path List <Node> tempList = new List <Node>(); //Gets the solution from the path finding tempList = pathFinding.GetSolution(); //If the solution has more then two tile if (tempList.Count > 2) { //Removes the first and last tile in the list tempList.RemoveAt(tempList.Count - 1); tempList.RemoveAt(0); //Loop for every tile in the list for (int i = tempList.Count - 1; i >= 0; i--) { //Adds the tile x and y values to the enemy's path currentPath.Add(new Vector2(tempList[i].Row * Tile.TILE_X_SIZE, tempList[i].Column * Tile.TILE_Y_SIZE)); } } //If the solution doesn't have more then two tiles, the current path is cleared else { currentPath.Clear(); } } //If the player is in view if (playerInView) { //The rotation angle towards the player is calculated CalcRotation(player.Position.X, player.Position.Y, 0, 0); //If the enemy is able to shoot if (shootDelayCount >= EnemyRifle.SHOT_DELAY && rifle.currentAmmo > 0) { //If the enemy is currently not shooting if (frameAnimation.AnimState == AnimationState.Shoot && frameAnimation.ShootingFrameDone || frameAnimation.AnimState != AnimationState.Shoot) { //The enemy is set to shoot and it's textures are changed frameAnimation.AnimState = AnimationState.Shoot; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), SHOOT_FRAME_DELAY); //The shooting delay is reset shootDelayCount = 0; } } } //If the player is not in view else { //If the player currently has a path its following if (currentPath.Count > 0) { //Calculates the rotation angle towards its next point in the path CalcRotation(currentPath[0].X, currentPath[0].Y, 0, 0); } } //If the enemy needs to reload if (rifle.currentAmmo == 0 && frameAnimation.AnimState != AnimationState.Reload) { //The enemy is set to reload frameAnimation.AnimState = AnimationState.Reload; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), RELOAD_FRAME_DELAY); } //If the enemy has a path it should follow if (currentPath.Count > 0) { //The enemy is set to move to the next point in its path MoveEnemy(); } //If the enemy does not have a path else { //The enemy is set to being idle if it's not doing anything else at the moment such as reloading or shooting if (HumanMoving && frameAnimation.AnimState != AnimationState.Reload && frameAnimation.AnimState != AnimationState.Shoot) { SetHumanIdle(); } } //The frame animation for the enemy is updated frameAnimation.Update(); //If the enemy is done shooting if (frameAnimation.AnimState == AnimationState.Shoot && frameAnimation.CurrFrame == SHOOT_FRAME_AMOUNT && frameAnimation.Count == SHOOT_FRAME_DELAY - 1) { //If the enemy is currently moving if (HumanMoving) { //The frame animation for the enemy is set to moving frameAnimation.AnimState = AnimationState.Move; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), MOVE_FRAME_DELAY); } //If the enemy is currently idle else { //The frame animation for the enemy is set to idle frameAnimation.AnimState = AnimationState.Idle; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), IDLE_FRAME_DELAY); } } //If the frame animation for the shooting is done and a bullet needs to be created if (frameAnimation.ShootingFrameDone) { //The direction for the bullet is calculated Vector2 direction = new Vector2((float)Math.Cos(rotationAngle), (float)Math.Sin(rotationAngle)); direction.Normalize(); //The point where the bullet spawns and the point at which the enemy rotates is calculated Vector2 pointToRotate = new Vector2(Position.X + EnemyRifle.BULLET_DISPLACEMENT_X, Position.Y + EnemyRifle.BULLET_DISPLACEMENT_Y); Vector2 centerPoint = new Vector2(Position.X + rotationOrigin.X, Position.Y + rotationOrigin.Y); //The new x and y for where the bullet should spawn is calculated int x = (int)(direction.X * (pointToRotate.X - centerPoint.X) - direction.Y * (pointToRotate.Y - centerPoint.Y) + centerPoint.X); int y = (int)(direction.Y * (pointToRotate.X - centerPoint.X) + direction.X * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y); //The projectile is created with the new spawn point and the ammo is decreased Projectiles.Add(new Projectile(new Vector2(x, y), ProjectileType.Bullet, EnemyRifle.BULLET_DAMAGE, EnemyRifle.BULLET_SPEED, rotationAngle, screenWidth, screenHeight)); rifle.currentAmmo--; //The frame animation for the shooting is set to not done so the bullet stop being created frameAnimation.ShootingFrameDone = false; } //If the frame animation for the reloading is done else if (frameAnimation.ReloadFrameDone) { //The ammo for the rifle is reset and the frame animation for the reloading is set to not done rifle.currentAmmo = EnemyRifle.AMMO_CAPACITY; frameAnimation.ReloadFrameDone = false; //If the enemy is moving if (HumanMoving) { //The frame animation for the enemy is set to moving frameAnimation.AnimState = AnimationState.Move; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), MOVE_FRAME_DELAY); } //If the enemy is idle else { //The frame animation for the enemy is set to idle frameAnimation.AnimState = AnimationState.Idle; frameAnimation.ResetFrame(rifle.GetTextures(frameAnimation.AnimState), IDLE_FRAME_DELAY); } } //For each projecitle in the list of projectiles foreach (Projectile projectile in Projectiles) { //The owner of the bullet is set to the current enemy projectile.BulletOwner = this; } //The shooting delay count is incremented shootDelayCount++; }