public void AddProjectile(eProjectile projectileType, Vector2 location, Vector2 direction, Player owner, int texIdx, Color drawColor, int tier)
        {
            BaseProjectile p = ProjectilePool[ProjectilePool.Count - 1];

            p.Initialize(projectileType, location, direction, owner, texIdx, tier);
            p.DrawColor = drawColor;
            Entities.Add(p);
            ProjectilePool.Remove(p);
        }
        void HandleCollision()
        {
            #region Pickups
            foreach (PlayerShip pShip in PlayerShips)
            {
                for (int i = 0; i < Pickups.Count; i++)
                {
                    if (pShip.AABB.Intersects(new Rectangle(Pickups[i].Location.Xi(), Pickups[i].Location.Yi(), 32, 32)))
                    {
                        switch (Pickups[i].PickupType)
                        {
                        case ePickupType.HP:
                            pShip.Heal(65);
                            break;

                        case ePickupType.Boom1:
                            PickupWeapon(pShip, eEnemyGunType.Boom1Enemy);
                            break;

                        case ePickupType.Aim:
                            PickupWeapon(pShip, eEnemyGunType.AutoAim);
                            break;

                        case ePickupType.Missile:
                            PickupWeapon(pShip, eEnemyGunType.Missile);
                            break;

                        case ePickupType.Speed:
                            if (!pShip.UpgradeSpeed())
                            {
                                pShip.Heal(DOUBLE_PICKUP_HEAL_AMOUNT);
                            }
                            break;

                        case ePickupType.Shield:
                            if (!pShip.UpgradeShield())
                            {
                                pShip.Heal(DOUBLE_PICKUP_HEAL_AMOUNT);
                            }
                            pShip.Shield.CurrentHP += 7;
                            break;

                        case ePickupType.DualMissile:
                            PickupWeapon(pShip, eEnemyGunType.DualMissile45);
                            break;

                        case ePickupType.ShieldRegen:
                            if (!pShip.UpgradeShieldRegen())
                            {
                                pShip.Heal(DOUBLE_PICKUP_HEAL_AMOUNT);
                            }
                            break;

                        default:
                            throw new NotImplementedException();
                        }

                        Pickups[i].IsDisposed = true;
                        pShip.Owner.Score    += (int)((5 + WaveNr) * Level.Instance.ScoreModifier);
                    }
                }
            }
            #endregion

            #region Scrapstation
            if (ActiveScrapStation != null && !ActiveScrapStation.IsGoingHome)
            {
                if (PlayerShips[0].AABB.Intersects(ActiveScrapStation.AABB))
                {
                    foreach (Rectangle2 rect in PlayerShips[0].CollisionRects)
                    {
                        foreach (Rectangle2 rect2 in ActiveScrapStation.CollisionRects)
                        {
                            if (rect.Absolute.Intersects(rect2.Absolute))
                            {
                                ActiveScrapStation.Visit(PlayerShips[0]);
                                return;
                            }
                        }
                    }
                }
            }
            #endregion

            #region Other Collisions
            // A note about the 'is' operator performance: http://stackoverflow.com/questions/686412/c-is-operator-performance
            for (int y = 0; y < BroadPhase.GRID_CNT; y++)
            {
                for (int x = 0; x < BroadPhase.GRID_CNT; x++)
                {
                    if (BroadPhase.Instance.Blocks[x, y].Entities.Count > 0)
                    {
                        for (int i = 0; i < BroadPhase.Instance.Blocks[x, y].Entities.Count; i++)
                        {
                            PlayerShip pShip = BroadPhase.Instance.Blocks[x, y].Entities[i] as PlayerShip;
                            if (pShip != null)
                            {
                                for (int j = 0; j < BroadPhase.Instance.Blocks[x, y].Entities.Count; j++)
                                {
                                    // Player <--> enemy projectile
                                    BaseProjectile p = BroadPhase.Instance.Blocks[x, y].Entities[j] as BaseProjectile;
                                    if (p != null)
                                    {
                                        if (p.Owner == null && !p.IsDisposed && pShip.AABB.Intersects(BroadPhase.Instance.Blocks[x, y].Entities[j].AABB))
                                        {
                                            foreach (Rectangle2 rect in pShip.CollisionRects)
                                            {
                                                if (p.AABB.Intersects(rect.Absolute))
                                                {
                                                    pShip.TakeDamage(p.Damage);
                                                    p.IsDisposed = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    // Player <--> enemy collision
                                    else
                                    {
                                        BaseEnemy e = BroadPhase.Instance.Blocks[x, y].Entities[j] as BaseEnemy;
                                        if (e != null)
                                        {
                                            if (!e.IsDisposed && pShip.AABB.Intersects(e.AABB))
                                            {
                                                foreach (Rectangle2 rect in pShip.CollisionRects)
                                                {
                                                    if (e.AABB.Intersects(rect.Absolute))
                                                    {
                                                        pShip.TakeDamage(e.CollisionDamage);
                                                        pShip.Owner.Kills++;
                                                        e.Die();
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            // enemy <--> player projectile
                            else if (BroadPhase.Instance.Blocks[x, y].Entities[i] is BaseEnemy)
                            {
                                BaseEnemy e = (BaseEnemy)BroadPhase.Instance.Blocks[x, y].Entities[i];

                                for (int j = 0; j < BroadPhase.Instance.Blocks[x, y].Entities.Count; j++)
                                {
                                    BaseProjectile p = BroadPhase.Instance.Blocks[x, y].Entities[j] as BaseProjectile;
                                    if (p != null)
                                    {
                                        if (p.Owner != null && e.AABB.Intersects(p.AABB) && !p.IsDisposed)
                                        {
                                            e.TakeDamage(p.Damage, p.Owner);
                                            p.IsDisposed = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            #endregion
        }
        public void Update(GameTime gameTime)
        {
            Engine.Instance.Audio.Update(gameTime);

            if (!IsPaused)
            {
                // Alow exit to main menu
                if (InputMgr.Instance.IsPressed(null, InputMgr.Instance.DefaultCancelKey, InputMgr.Instance.DefaultCancelButton))
                {
                    Engine.Instance.ActiveState = new MainMenu(true);
                    return;
                }

                // ABH
                if (!ABH.IsDone)
                {
                    ABH.Update();
                }

                // Spawn
                SpawnDelayTimer.Update(gameTime);
                Spawn();

                // Spawn bonus
                if (SpawnClrBonusIsShowing)
                {
                    SpawnClrBonusX -= 6f;
                    if (SpawnClrBonusX < -400)
                    {
                        SpawnClrBonusIsShowing = false;
                    }
                }

                // Clear broadphase
                BroadPhase.Instance.ClearEntities();

                // Update entities
                for (int i = 0; i < Entities.Count; i++)
                {
                    Entities[i].Update(gameTime);
                }

                // Pools
                ExplosionPool.CleanUp();

                // Scrapstation
                if (ActiveScrapStation != null)
                {
                    ActiveScrapStation.Update(gameTime);
                    if (ActiveScrapStation.IsDisposed)
                    {
                        ActiveScrapStation = null;
                    }
                }

                // update pickups
                for (int i = 0; i < Pickups.Count; i++)
                {
                    Pickups[i].Update(gameTime);
                }

                for (int i = 0; i < Entities.Count; i++)
                {
                    if (Entities[i].IsDisposed)
                    {
                        // Projectile pool
                        BaseProjectile p = Entities[i] as BaseProjectile;
                        if (p != null)
                        {
                            ProjectilePool.Add(p);
                        }

                        Entities.RemoveAt(i);
                        i--;
                    }
                }

                // Visuals
                for (int i = 0; i < Visuals.Count; i++)
                {
                    Visuals[i].Update(gameTime);
                    if (Visuals[i].IsDisposed)
                    {
                        Visuals.RemoveAt(i);
                        i--;
                    }
                }

                // Pickup pool
                for (int i = 0; i < Pickups.Count; i++)
                {
                    if (Pickups[i].IsDisposed)
                    {
                        PickupPool.Add(Pickups[i]);
                        Pickups.RemoveAt(i);
                        i--;
                    }
                }

                // Collision
                HandleCollision();
                // Background scroller
                ScrollBG.Update(gameTime);
            }
            if (InputMgr.Instance.IsPressed(null, Keys.P, Buttons.Y))
            {
                IsPaused = !IsPaused;
            }
        }