/// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            ScreenManager.Sound.Update();

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
            {
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
                ScreenManager.Sound.Pause();
            }
            else
            {
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);
                ScreenManager.Sound.Resume();
            }

            if (IsActive)
            {
                currTime = (float)gameTime.TotalGameTime.TotalMilliseconds;

                ScreenManager.Sound.PlayEngine(shipOne.Position, shipTwo.Position);
                ScreenManager.Sound.PlayEngine(shipTwo.Position, shipOne.Position);

                if (shipOne.mach > 0)
                    ScreenManager.Sound.PlayAfterburner(shipOne.Position, shipTwo.Position);

                if (shipTwo.mach > 0)
                    ScreenManager.Sound.PlayAfterburner(shipTwo.Position, shipOne.Position);

                // Update the ship
                UpdateShip(gameTime, shipOne);
                UpdateShip(gameTime, shipTwo);

                CheckBoundaries(gameTime);

                // Update the camera to chase the new target
                UpdateCameraChaseTarget();

                // The chase camera's update behavior is the springs, but we can
                // use the Reset method to have a locked, spring-less camera
                cameraOne.Update(gameTime);
                cameraTwo.Update(gameTime);

                // Update bullets and missiles
                //UpdateAmmo(gameTime, shipOne, bulletOneList, missileOneList);
                //UpdateAmmo(gameTime, shipTwo, bulletTwoList, missileTwoList);
                pOneHUD.Update(gameTime, shipOne.Direction, shipOne.life, shipOne.leftBulletAmt, shipOne.leftMissileAmt, shipOne.rightBulletAmt, shipOne.rightMissileAmt, pOneWarning, shipOneWarningCountdown, shipOne.mach);
                pTwoHUD.Update(gameTime, shipTwo.Direction, shipTwo.life, shipTwo.leftBulletAmt, shipTwo.leftMissileAmt, shipTwo.rightBulletAmt, shipTwo.rightMissileAmt, pTwoWarning, shipTwoWarningCountdown, shipTwo.mach);
                UpdateMissileTrail(missileOneList);

                for (int i = 0; i < powerUpList.Count; i++)
                {
                    powerUpList[i].Update(gameTime);
                    if (powerUpList[i].boundingSphere.Intersects(shipOne.boundingSphere))
                    {

                        shipOne.leftBulletAmt = shipOne.maxBullets;
                        shipOne.rightBulletAmt = shipOne.maxBullets;

                        ScreenManager.Sound.PlayWeaponToggle(shipOne.Position, shipTwo.Position);
                        powerUpList.RemoveAt(i);
                        break;
                    }
                    if (powerUpList[i].boundingSphere.Intersects(shipTwo.boundingSphere))
                    {
                        shipTwo.leftBulletAmt = shipTwo.maxBullets;
                        shipTwo.rightBulletAmt = shipTwo.maxBullets;

                        ScreenManager.Sound.PlayWeaponToggle(shipTwo.Position, shipOne.Position);
                        powerUpList.RemoveAt(i);
                        break;
                    }
                }

                if (powerUpList.Count < 10)
                {
                    PowerUp powerup = new PowerUp(ScreenManager.Game);

                    for (int i = buildingArray.Count - 1; i >= 0; i--)
                    {
                        while (powerup.boundingSphere.Intersects(buildingArray[i].boundingBox))
                        {
                            powerup.position = new Vector3(randomiser.Next(-460000, 500000),
                                                                randomiser.Next(5000, 450000),
                                                                randomiser.Next(-460000, 500000));
                        }
                    }

                    powerUpList.Add(powerup);
                }

                CheckGameOver(gameTime);

                #region CartoonShader
                // Update the sketch overlay texture jitter animation.
                if (Settings.SketchJitterSpeed > 0)
                {
                    timeToNextJitter -= gameTime.ElapsedGameTime;

                    if (timeToNextJitter <= TimeSpan.Zero)
                    {
                        sketchJitter.X = (float)random.NextDouble();
                        sketchJitter.Y = (float)random.NextDouble();

                        timeToNextJitter += TimeSpan.FromSeconds(Settings.SketchJitterSpeed);
                    }
                }
                #endregion

            }
            else
            {
            #if XBOX360
                GamePad.SetVibration((PlayerIndex)ControllingPlayer, 0, 0);
                GamePad.SetVibration((PlayerIndex)ScreenManager.ControllingPlayerTwo, 0, 0);
            #else

            #endif
            }
        }
        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void Activate(bool instancePreserved)
        {
            if (!instancePreserved)
            {
                if (Content == null)
                    Content = new ContentManager(ScreenManager.Game.Services, "Content");

                // collision debugging
                DebugShapeRenderer.Initialize(ScreenManager.GraphicsDevice);

                #region SplitScreen

                // Create the texture we'll use to draw our viewport edges.
                blank = new Texture2D(ScreenManager.GraphicsDevice, 1, 1);
                blank.SetData(new[] { Color.White });

                if (OptionsMenuScreen.currentSplitScreen == OptionsMenuScreen.SplitScreen.Horizontal)
                {
                    // Create the viewports
                    playerOneViewport = new Viewport
                    {
                        MinDepth = 0,
                        MaxDepth = 1,
                        X = 0,
                        Y = 0,
                        Width = ScreenManager.GraphicsDevice.Viewport.Width,
                        Height = ScreenManager.GraphicsDevice.Viewport.Height / 2,
                    };
                    playerTwoViewport = new Viewport
                    {
                        MinDepth = 0,
                        MaxDepth = 1,
                        X = 0,
                        Y = ScreenManager.GraphicsDevice.Viewport.Height / 2,
                        Width = ScreenManager.GraphicsDevice.Viewport.Width,
                        Height = ScreenManager.GraphicsDevice.Viewport.Height / 2,
                    };
                }
                else
                {
                    // Create the viewports
                    playerOneViewport = new Viewport
                    {
                        MinDepth = 0,
                        MaxDepth = 1,
                        X = 0,
                        Y = 0,
                        Width = ScreenManager.GraphicsDevice.Viewport.Width / 2,
                        Height = ScreenManager.GraphicsDevice.Viewport.Height,
                    };
                    playerTwoViewport = new Viewport
                    {
                        MinDepth = 0,
                        MaxDepth = 1,
                        X = ScreenManager.GraphicsDevice.Viewport.Width / 2,
                        Y = 0,
                        Width = ScreenManager.GraphicsDevice.Viewport.Width / 2,
                        Height = ScreenManager.GraphicsDevice.Viewport.Height,
                    };
                }

                // Create the view and projection matrix for each of the viewports
                playerOneView = Matrix.CreateLookAt(
                    new Vector3(400f, 900f, 200f),
                    new Vector3(-100f, 0f, 0f),
                    Vector3.Up);
                playerOneProjection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.PiOver4, playerOneViewport.AspectRatio, 10f, 5000f);

                playerTwoView = Matrix.CreateLookAt(
                    new Vector3(0f, 800f, 800f),
                    Vector3.Zero,
                    Vector3.Up);
                playerTwoProjection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.PiOver4, playerTwoViewport.AspectRatio, 10f, 5000f);

                #endregion

                #region ChaseCamera

                gameFont = Content.Load<SpriteFont>("Fonts/gamefont");
                if (SelectionScreen.playerOneSelect == 1)
                    playerOneModel = Content.Load<Model>("Models/F-16/F-16_Game");
                else
                    playerOneModel = Content.Load<Model>("Models/MiG-29/MiG-29_Game");
                if (SelectionScreen.playerTwoSelect == 1)
                    playerTwoModel = Content.Load<Model>("Models/F-16/F-16_Game");
                else
                    playerTwoModel = Content.Load<Model>("Models/MiG-29/MiG-29_Game");
                groundModel = Content.Load<Model>("Models/Terrain/terrain");
                bulletModel = Content.Load<Model>("Models/Bullet/bullet");
                missileModel = Content.Load<Model>("Models/Missile/missile");
                skyModel = Content.Load<Model>("Models/SkyDome/skydome");

                if (SelectionScreen.playerOneSelect == 1)
                    shipOne = new Ship(ScreenManager.GraphicsDevice, (PlayerIndex)ControllingPlayer, new Vector3(-74000, 0, 400000), new Vector3(0, 0, -1));
                else
                    shipOne = new Ship(ScreenManager.GraphicsDevice, (PlayerIndex)ControllingPlayer, new Vector3(-74000, 0, 400000), new Vector3(0, 0, -1));

                if (SelectionScreen.playerTwoSelect == 1)
                    shipTwo = new Ship(ScreenManager.GraphicsDevice, (PlayerIndex)ScreenManager.ControllingPlayerTwo, new Vector3(18000, 0, -400000), new Vector3(0, 0, 1));
                else
                    shipTwo = new Ship(ScreenManager.GraphicsDevice, (PlayerIndex)ScreenManager.ControllingPlayerTwo, new Vector3(18000, 0, -400000), new Vector3(0, 0, 1));

                // Create the chase camera
                cameraOne = new ChaseCamera();
                cameraTwo = new ChaseCamera();

                // Set the camera offsets
                cameraOne.DesiredPositionOffset = new Vector3(0.0f, 2000.0f, 3500.0f);
                cameraOne.LookAtOffset = new Vector3(0.0f, 150.0f, 0.0f);
                cameraTwo.DesiredPositionOffset = new Vector3(0.0f, 2000.0f, 3500.0f);
                cameraTwo.LookAtOffset = new Vector3(0.0f, 150.0f, 0.0f);

                // Set camera perspective
                cameraOne.NearPlaneDistance = 1.0f;
                cameraOne.FarPlaneDistance = 1550000.0f;
                cameraTwo.NearPlaneDistance = 1.0f;
                cameraTwo.FarPlaneDistance = 1550000.0f;

                // Set the camera aspect ratio
                // This must be done after the class to base.Initalize() which will
                // initialize the graphics device.
                cameraOne.AspectRatio = (float)playerOneViewport.Width / playerOneViewport.Height;
                cameraTwo.AspectRatio = (float)playerTwoViewport.Width / playerTwoViewport.Height;

                // Perform an inital reset on the camera so that it starts at the resting
                // position. If we don't do this, the camera will start at the origin and
                // race across the world to get behind the chased object.
                // This is performed here because the aspect ratio is needed by Reset.
                UpdateCameraChaseTarget();
                cameraOne.Reset();
                cameraTwo.Reset();

                #endregion

                #region HUD
                pOneHUD = new HUD(ScreenManager.Game, playerOneViewport, PlayerIndex.One);
                pTwoHUD = new HUD(ScreenManager.Game, playerTwoViewport, PlayerIndex.Two);
                #endregion

                #region Particles

                explosionParticles = new ParticleSystem(ScreenManager.Game, Content, "Particles/ExplosionSettings");
                explosionSmokeParticles = new ParticleSystem(ScreenManager.Game, Content, "Particles/ExplosionSmokeSettings");
                missileTrailParticles = new ParticleSystem(ScreenManager.Game, Content, "Particles/ProjectileTrailSettings");

                explosionSmokeParticles.DrawOrder = 200;
                missileTrailParticles.DrawOrder = 300;
                explosionParticles.DrawOrder = 400;

                explosionParticles.Visible = false;
                explosionSmokeParticles.Visible = false;
                missileTrailParticles.Visible = false;

                ScreenManager.Game.Components.Add(missileTrailParticles);
                ScreenManager.Game.Components.Add(explosionParticles);
                ScreenManager.Game.Components.Add(explosionSmokeParticles);

                #endregion

                #region CartoonShader

                postprocessEffect = Content.Load<Effect>("CartoonShader/PostprocessEffect");
                sketchTexture = Content.Load<Texture2D>("CartoonShader/SketchTexture");
                Effect cartoonEffect = Content.Load<Effect>("CartoonShader/CartoonEffect");

                ChangeEffectUsedByModel(playerOneModel, cartoonEffect);
                ChangeEffectUsedByModel(playerTwoModel, cartoonEffect);

                // Create two custom rendertargets.
                PresentationParameters pp = ScreenManager.GraphicsDevice.PresentationParameters;

                sceneRenderTarget = new RenderTarget2D(ScreenManager.GraphicsDevice,
                                                       pp.BackBufferWidth, pp.BackBufferHeight, false,
                                                       pp.BackBufferFormat, pp.DepthStencilFormat);

                normalDepthRenderTarget = new RenderTarget2D(ScreenManager.GraphicsDevice,
                                                             pp.BackBufferWidth, pp.BackBufferHeight, false,
                                                             pp.BackBufferFormat, pp.DepthStencilFormat);

                #endregion

                // Initalise the motor
                //pOneVibrateRight = 0;
                //pOneVibrateLeft = 0;
                //pTwoVibrateRight = 0;
                //pTwoVibrateLeft = 0;

                // Initalise player's warning when out of battlezone
                pOneWarning = false;
                pTwoWarning = false;

                for (int i = 0; i < 100; i++)
                {
                    Building building = new Building(ScreenManager.Game);
                    buildingArray.Add(building);
                }

                for (int i = 0; i < 20; i++)
                {
                    PowerUp powerup = new PowerUp(ScreenManager.Game);
                    powerUpList.Add(powerup);
                }

                int width_Z = 170000;
                int width_X = 45000;

                runway01_bounding = new BoundingBox(new Vector3(-74000 - width_X, 0, 400000 - width_Z),
                   new Vector3(-74000 + width_X, 10000, 400000 + width_Z));

                runway02_bounding = new BoundingBox(new Vector3(18000 - width_X, 0, -400000 - width_Z),
                    new Vector3(18000 + width_X, 10000, -400000 + width_Z));

                //remove buildings if collide with runway
                for (int i = buildingArray.Count - 1; i >= 0; i--)
                {
                    if (buildingArray[i].boundingBox.Intersects(runway01_bounding) ||
                        buildingArray[i].boundingBox.Intersects(runway02_bounding))
                    {
                        buildingArray.RemoveAt(i);
                    }
                }

                //remove buildings when collide with each other.
                for (int i = buildingArray.Count - 1; i >= 1; i--)
                {
                    if (buildingArray[i].boundingBox.Intersects(buildingArray[i - 1].boundingBox))
                    {
                        buildingArray.RemoveAt(i);
                    }
                }

                //re-position powerups when collide with buildings
                for (int i = powerUpList.Count - 1; i >= 0; i--)
                {
                    for (int k = buildingArray.Count - 1; k >= 0; k--)
                    {
                        while(powerUpList[i].boundingSphere.Intersects(buildingArray[k].boundingBox))
                        {
                            powerUpList[i].position = new Vector3(randomiser.Next(-460000, 500000),
                                                                randomiser.Next(5000, 450000),
                                                                randomiser.Next(-460000, 500000));
                        }
                    }
                }

                //re-position powerups when collide with runways
                for (int i = powerUpList.Count - 1; i >= 0; i--)
                {
                    while (powerUpList[i].boundingSphere.Intersects(runway01_bounding) ||
                        powerUpList[i].boundingSphere.Intersects(runway02_bounding))
                    {
                        powerUpList[i].position = new Vector3(randomiser.Next(-460000, 500000),
                                                            randomiser.Next(5000, 450000),
                                                            randomiser.Next(-460000, 500000));
                    }
                }

                textFader = (TextFader)ScreenManager.Game.Services.GetService(typeof(TextFader));

                // once the load has finished, we use ResetElapsedTime to tell the game's
                // timing mechanism that we have just finished a very long frame, and that
                // it should not try to catch up.
                ScreenManager.Game.ResetElapsedTime();
            }
        }