/// <summary> /// Move a tank based on given tank and movement, if tank will collide with a wall, tank will not move /// If tank goes out of the world, tank will be wrapped back into the world /// </summary> /// <param name="movement">movement command string, either "none", "left", "right", "up", or "down"</param> private void HandleTankMovement(string movement, Tank tank) { if (movement != "none") { //Get the direction vector base on Vector2D dir = GetDirection(movement, tank); //Set tank's orientation base on the wasd tank.Orientation = dir; //Compute next frame location Vector2D nextframelocation = tank.Location + dir * _tankspeed; //If tank will not collide with wall and in world, the update the tank location based on current engine strength (tank speed) and given direction if (!CollisionDetect.ObjectWallsCollision(tank, nextframelocation, theWorld) && InWorld(nextframelocation)) { tank.Location = nextframelocation; } //Wrap around to the other side if (!InWorld(nextframelocation)) { //Horizontal direction if (Math.Abs(nextframelocation.GetX()) > (theWorld.Size / 2)) { tank.Location = new Vector2D(-nextframelocation.GetX(), nextframelocation.GetY()); } //Vertical direction if (Math.Abs(nextframelocation.GetY()) > (theWorld.Size / 2)) { tank.Location = new Vector2D(nextframelocation.GetX(), -nextframelocation.GetY()); } } } }
/// <summary> /// Generate a random location for powerup that doesn't collides with any walls /// </summary> /// <returns>Vector2D location</returns> private Vector2D GeneratePowerupLocation() { Random rng = new Random(); while (true) { Vector2D loc = new Vector2D(rng.Next(-theWorld.Size / 2, theWorld.Size / 2), rng.Next(-theWorld.Size / 2, theWorld.Size / 2)); //Make sure it doesn't collide with other walls if (!CollisionDetect.ObjectWallsCollision(new Powerup(), loc, theWorld)) { return(loc); } } }
/// <summary> /// Handle all logic relating to projectile and update the current projectile: /// If projectile collides with a tank other than its owner, projectile will inflict damage on tank being hit and be marked as "died" /// If projectile destroy another tank, projectile's owner will gain one point score, and setting dead tank in respawn state /// If projectile collides with a wall or go out of the world, projectile will be marked as "died" /// </summary> /// <param name="proj"></param> private void UpdateProjectile(Projectile proj) { //Check if projectile collides with any walls bool projwallCollision = CollisionDetect.ObjectWallsCollision(proj, proj.Location, theWorld); //Check if projectile collides with any tanks other than the owner bool projothertankCollision = CollisionDetect.ProjOtherTanksCollision(proj, out Tank hitTank, theWorld); //To check if projectile still in the world bool projinWorld = InWorld(proj.Location); //If proj didn't collide with any of tanks and walls and still in the world, projectile keep flying if (!projwallCollision && !projothertankCollision && projinWorld) { //Update projectile location based on given proj speed proj.Location += proj.Direction * _projspeed; } else if (projothertankCollision) { if (hitTank.HitPoints > 0) { //Do some damage to hitTank hitTank.HitPoints--; if (hitTank.HitPoints == 0) { //Mark it died hitTank.Died = true; //Enter respawn state hitTank.FramesInRespawn = 0; //Gain one score for proj's owner theWorld.Tanks[proj.Owner].Score++; } } } if (projwallCollision || projothertankCollision || !projinWorld) { proj.Died = true; //Remove it after sending _diedprojectiles.Add(proj.ID); } }