public Shell(Game game, Vector3 p_velocity, Vector3 p_cannonEnd, Tank p_owner) : base(game) { tankGame = game; velocity = p_velocity; location = p_cannonEnd; cannonEnd = p_cannonEnd; time = 0; gravity = 980.0665f; radius = 15; owner = p_owner; camera = (GameServices.CameraState)Game.Services.GetService( typeof(GameServices.CameraState)); audio = (GameServices.AudioLibrary)Game.Services.GetService( typeof(GameServices.AudioLibrary)); }
/// <summary> /// Check tank on tank collision /// Seeing as the tanks cannot travel vertically, all these calculations are in 2D /// </summary> /// <param name="tank">other tank</param> bool CheckTankCollision(Tank tank) { // First checks to see if this tank is within 921 units from the other tank (920.2 units is the furthest collision possible) if (Vector3.Distance(tank.Location,tankLocation) < 921 && tank != this) { //relative location and rotation float rot = tank.Rotation-totalRotation; //Calculate other tanks location relative to this tank Vector2 loc = new Vector2((tank.Location.X - tankLocation.X) * (float)Math.Cos(totalRotation) - (tank.Location.Z - tankLocation.Z) * (float)Math.Sin(totalRotation), (tank.Location.X - tankLocation.X) * (float)Math.Sin(totalRotation) + (tank.Location.Z - tankLocation.Z) * (float)Math.Cos(totalRotation)); //Calculate other tanks corners relative to this tank Vector2 topLeft = new Vector2(loc.X + tankSize.X * (float)Math.Cos(rot) + tankSize.Z *(float)Math.Sin(rot), loc.Y + tankSize.Z * (float)Math.Cos(rot) - tankSize.X *(float)Math.Sin(rot)); Vector2 topRight = new Vector2(loc.X - tankSize.X * (float)Math.Cos(rot) + tankSize.Z * (float)Math.Sin(rot), loc.Y + tankSize.Z * (float)Math.Cos(rot) + tankSize.X *(float)Math.Sin(rot)); Vector2 botLeft = new Vector2(loc.X + tankSize.X * (float)Math.Cos(rot) - tankSize.Z * (float)Math.Sin(rot), loc.Y - tankSize.Z * (float)Math.Cos(rot) - tankSize.X *(float)Math.Sin(rot)); Vector2 botRight = new Vector2(loc.X - tankSize.X * (float)Math.Cos(rot) - tankSize.Z * (float)Math.Sin(rot), loc.Y - tankSize.Z * (float)Math.Cos(rot) + tankSize.X *(float)Math.Sin(rot)); Vector2 hitBox = new Vector2(tankSize.X, tankSize.Z); //Check to see if other tanks corners are in this tank if(InsideRectangle(topLeft,hitBox)|| InsideRectangle(topRight,hitBox)|| InsideRectangle(botLeft,hitBox) || InsideRectangle(botRight,hitBox)) return true; //Checks to see if this tanks corners are in the other tank else if(InsideTriangle(topLeft, topRight, botLeft, hitBox)|| InsideTriangle(topLeft, topRight, botLeft, new Vector2(-hitBox.X, hitBox.Y))|| InsideTriangle(topLeft, topRight, botLeft, new Vector2(hitBox.X, -hitBox.Y))|| InsideTriangle(topLeft, topRight, botLeft, new Vector2(-hitBox.X, -hitBox.Y))|| InsideTriangle(botRight, topRight, botLeft, hitBox)|| InsideTriangle(botRight, topRight, botLeft, new Vector2(-hitBox.X, hitBox.Y))|| InsideTriangle(botRight, topRight, botLeft, new Vector2(hitBox.X, -hitBox.Y))|| InsideTriangle(botRight, topRight, botLeft, new Vector2(-hitBox.X, -hitBox.Y))) return true; } return false; }
/// <summary> /// Check shell on tank collision it is assumed the shell is low enough to hit the tank. /// This only gets checked if the shells edge is below the height of the Tank, thus all calculations are in 2D /// </summary> /// <param name="tank">Tank</param> bool CheckTankCollision(Tank tank) { // First checks to see if this shell is within 596 units from the tank (595.4 units is the furthest collision possible) if (Vector3.Distance(tank.Location, location) < 596 && tank != owner) { //relative location and rotation float rot = tank.Rotation; //Calculate shells location relative to the tank Vector3 loc = new Vector3( (location.X - tank.Location.X) * (float)Math.Cos(rot) - (location.Z - tank.Location.Z) * (float)Math.Sin(rot), location.Y, (location.X - tank.Location.X) * (float)Math.Sin(rot) + (location.Z - tank.Location.Z) * (float)Math.Cos(rot)); Vector3 vel = new Vector3(velocity.X * (float)Math.Cos(rot) - velocity.Z * (float)Math.Sin(rot), velocity.Y, velocity.X * (float)Math.Sin(rot) + velocity.Z * (float)Math.Cos(rot)); //Create an enlarged hitbox based on the shell's radius Vector3 hitBox = new Vector3(tank.Size.X + radius, tank.Size.Y + radius, tank.Size.Z + radius); //Check to see if the shell passes through the tanks hitbox if (CheckHitBoxCollision(hitBox, vel, loc)) { tank.Health -= 1; if (tank.Health <= 0) tankGame.Components.Remove(tank); return true; } } return false; }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { //Initialize Input input = new GameServices.InputState(); input.Update(); Services.AddService(typeof(GameServices.InputState), input); //create camera camera = new GameServices.CameraState( MathHelper.PiOver4, (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height, 1.0f, 100000.0f); Services.AddService(typeof(GameServices.CameraState), camera); //create audip audio = new GameServices.AudioLibrary(); audio.InitializeAudio(); Services.AddService(typeof(GameServices.AudioLibrary), audio); //create tanks playerTank = new Objects.Tank(this, new Vector3(0, 0, 0)); playerTank.Health = 10; playerTank.AI = false; Components.Add(playerTank); //buildings buildings = new List<List<Objects.Building>>(); List<Objects.Building> listception = new List<Objects.Building>(); Objects.Building build; for (int i = 1; i <= worldsize.Y / 3000; i++) { for (int j = 1; j <= worldsize.X / 3000; j++) { build = new Objects.Building(this, new Vector3(i * 3000 + 435 - worldsize.Y / 2, 0, j * 3000 + 435 - worldsize.X / 2)); build.Enabled = false; Components.Add(build); } } Random x = new Random(); int n = x.Next(5, 50); Objects.Tank tank; for (int i = 0; i < n; i++) { do tank = new Objects.Tank(this, new Vector3(x.Next(-15, 16) * 3000, 0, x.Next(-15, 16) * 3000)); while (tank.CollisionDetection()); Components.Add(tank); } camera.Update(playerTank.Location, playerTank.TurretRotation); GenerateGround(worldsize.X, worldsize.Y); base.Initialize(); }