public bool UpdateNPC(NPC npc, Player player, List<Obstacle> visibleObstacles, GameTime gameTime) { if (npc.CanSeePlayer(player, visibleObstacles)) return true; switch (npc.tag) { case NPCType.PoliceA: { npc.MoveForward(gameTime, 1.0f); if(collisionController.IllegalMove(npc)) npc.MoveBackward(gameTime, 1.0f); npc.RotateRight(gameTime, 1.0f); } break; case NPCType.PoliceB: npc.stateTime += gameTime.ElapsedGameTime.Milliseconds; double angleToPlayer = Math.Atan2(-1*((double)(player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2))), ((double)(player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))); double facingAngle = Math.Atan2(-1*npc.vision.viewDirection.Y, npc.vision.viewDirection.X); double turnToAngle = facingAngle - angleToPlayer; while (turnToAngle < -1 * MathHelper.Pi) turnToAngle += MathHelper.TwoPi; while (turnToAngle > MathHelper.Pi) turnToAngle -= MathHelper.TwoPi; switch (npc.state) { case NPCState.PatrolRight: npc.MoveForward(gameTime, 1.0f); if (collisionController.IllegalMove(npc)) { npc.MoveBackward(gameTime, 1.0f); npc.state = NPCState.PatrolRightBackwards; npc.stateTime = 0; } if (Math.Abs(turnToAngle) < npc.vision.viewAngle && visibleObstacles.Count == 0 && player.isVisible && npc.vision.maxViewDistance * 1.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Chase; npc.stateTime = 0; } else if (player.isVisible && npc.vision.maxViewDistance / 2.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Investigate; npc.stateTime = 0; } else if (npc.stateTime > 3000) { npc.state = NPCState.PatrolLeft; npc.stateTime = 0; } else npc.RotateRight(gameTime, 1.0f); break; case NPCState.PatrolLeft: npc.MoveForward(gameTime, 1.0f); if (collisionController.IllegalMove(npc)) { npc.MoveBackward(gameTime, 1.0f); npc.state = NPCState.PatrolLeftBackwards; npc.stateTime = 0; } if (Math.Abs(turnToAngle) < npc.vision.viewAngle && visibleObstacles.Count == 0 && player.isVisible && npc.vision.maxViewDistance * 1.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Chase; npc.stateTime = 0; } else if (player.isVisible && npc.vision.maxViewDistance / 2.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Investigate; npc.stateTime = 0; } else if (npc.stateTime > 3000) { npc.state = NPCState.PatrolRight; npc.stateTime = 0; } else npc.RotateLeft(gameTime, 1.0f); break; case NPCState.PatrolLeftBackwards: npc.MoveBackward(gameTime, 1.0f); if (collisionController.IllegalMove(npc)) { npc.MoveForward(gameTime, 1.0f); npc.state = NPCState.PatrolLeft; npc.stateTime = 0; } if (Math.Abs(turnToAngle) < npc.vision.viewAngle && visibleObstacles.Count == 0 && player.isVisible && npc.vision.maxViewDistance * 1.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Chase; npc.stateTime = 0; } else if (player.isVisible && npc.vision.maxViewDistance / 2.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Investigate; npc.stateTime = 0; } else if (npc.stateTime > 250) { npc.state = NPCState.PatrolLeft; npc.stateTime = 0; } else npc.RotateLeft(gameTime, 2.5f); break; case NPCState.PatrolRightBackwards: npc.MoveBackward(gameTime, 1.0f); if (collisionController.IllegalMove(npc)) { npc.MoveForward(gameTime, 1.0f); npc.state = NPCState.PatrolRight; npc.stateTime = 0; } if (Math.Abs(turnToAngle) < npc.vision.viewAngle && visibleObstacles.Count == 0 && player.isVisible && npc.vision.maxViewDistance * 1.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Chase; npc.stateTime = 0; } else if (player.isVisible && npc.vision.maxViewDistance / 2.5 > Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.Investigate; npc.stateTime = 0; } else if (npc.stateTime > 250) { npc.state = NPCState.PatrolRight; npc.stateTime = 0; } else npc.RotateRight(gameTime, 2.5f); break; case NPCState.Chase: if (!player.isVisible || npc.vision.maxViewDistance*2 < Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.PatrolLeft; //Randomize npc.stateTime = 0; break; } if (Math.Abs(turnToAngle) > .05) { if (turnToAngle > 0) npc.RotateLeft(gameTime, 2.0f); else if (turnToAngle < 0) npc.RotateRight(gameTime, 2.0f); } npc.MoveForward(gameTime, 2.0f); if (collisionController.IllegalMove(npc)) { npc.MoveBackward(gameTime, 2.0f); npc.MoveRight(gameTime, 2.0f); npc.state = NPCState.PatrolLeft; //Randomize npc.stateTime = 0; //if (turnToAngle > 0) //{ // npc.MoveUp(gameTime, 2.0f); // if (collisionController.IllegalMove(npc)) // { // npc.MoveDown(gameTime, 2.0f); // if (Math.Abs(turnToAngle) < MathHelper.PiOver2) // { // npc.MoveRight(gameTime, 2.0f); // if (collisionController.IllegalMove(npc)) // { // npc.MoveLeft(gameTime, 2.0f); // npc.state = NPCState.PatrolLeft; //Randomize // npc.stateTime = 0; // } // } // } //} //else if (turnToAngle < 0) //{ // npc.MoveDown(gameTime, 2.0f); // if (collisionController.IllegalMove(npc)) // { // npc.MoveUp(gameTime, 2.0f); // if (Math.Abs(turnToAngle) < MathHelper.PiOver2) // { // npc.MoveLeft(gameTime, 2.0f); // if (collisionController.IllegalMove(npc)) // { // npc.MoveRight(gameTime, 2.0f); // npc.state = NPCState.PatrolLeft; //Randomize // npc.stateTime = 0; // } // } // } //} } break; case NPCState.Investigate: if (!player.isVisible || npc.vision.maxViewDistance / 2 < Math.Abs(((player.worldRectangle.Y + (player.worldRectangle.Height / 2)) - (npc.worldRectangle.Y + (npc.worldRectangle.Height / 2)))) + Math.Abs((player.worldRectangle.X + (player.worldRectangle.Width / 2)) - (npc.worldRectangle.X + (npc.worldRectangle.Width / 2)))) { npc.state = NPCState.PatrolLeft; //Randomize npc.stateTime = 0; } else if (Math.Abs(turnToAngle) < npc.vision.viewAngle / 2 && visibleObstacles.Count == 0 && player.isVisible) { npc.state = NPCState.Chase; npc.stateTime = 0; } else if (turnToAngle > 0) npc.RotateLeft(gameTime, 3.0f); else if (turnToAngle < 0) npc.RotateRight(gameTime, 3.0f); break; } break; } return false; }