void SpawnScrapStation()
        {
            ScrapStation ss = ScrapStationPool.New();

            ss.Initialize(new Vector2(Maths.RandomNr(0, Engine.Instance.Width - 128), Maths.RandomNr(-256, -174)));
            ActiveScrapStation = ss;
        }
        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;
            }
        }
        public Level(int startingWave, int dropRateModifier, int waveDelayInMS, int area, float scoreModifier, string music, ePlaneType planeType, string shipName)
        {
            // Music
            Music = music;
            MP3MusicMgr.Instance.PlayMusic(music);

            ScoreModifier           = scoreModifier;
            WaveNr                  = startingWave;
            ItemEnemy.LastWaveSpawn = WaveNr;
            DropRateModifier        = dropRateModifier;
            SpawnDelayTimer         = new SimpleTimer(waveDelayInMS);
            ScrollBG                = new ScrollBG("bg0" + area.ToString());
            Shop.IsFirstVisit       = true;
            if (area == 3 || area == 4)
            {
                MG1.MGDrawColor = Color.DarkRed;
                MG2.MGDrawColor = Color.DarkBlue;
            }
            else
            {
                MG1.MGDrawColor = MG2.MGDrawColor = Color.White;
            }
            WaveNrSB = new StringBuilder(startingWave.ToString(), 2);

            BroadPhase.Instance = new BroadPhase(128);
            BroadPhase.Instance.Init();

            Level.Instance = this;
            #region Generic Pools
            MGPool            = new Pool <MG1>(25, true, g => !g.IsDisposed, () => MG1.PoolConstructor());
            MG2Pool           = new Pool <MG2>(1, true, g => !g.IsDisposed, () => MG2.PoolConstructor());
            AutoAimPool       = new Pool <AutoAim>(100, true, g => !g.IsDisposed, () => AutoAim.PoolConstructor());
            BoomPool          = new Pool <Boom1>(100, true, g => !g.IsDisposed, () => Boom1.PoolConstructor());
            MissilePool       = new Pool <Missile>(80, true, g => !g.IsDisposed, () => Missile.PoolConstructor());
            DualMissile45Pool = new Pool <DualMissile45>(80, true, g => !g.IsDisposed, () => DualMissile45.PoolConstructor());
            // Enemies
            StraightEnemyPool = new Pool <StraightEnemy>(200, true, e => !e.IsDisposed, () => StraightEnemy.PoolConstructor());
            SuiciderEnemyPool = new Pool <SuiciderEnemy>(60, true, e => !e.IsDisposed, () => SuiciderEnemy.PoolConstructor());
            ItemEnemyPool     = new Pool <ItemEnemy>(10, true, e => !e.IsDisposed, () => ItemEnemy.PoolConstructor());
            ZigZagEnemyPool   = new Pool <ZigZagEnemy>(130, true, e => !e.IsDisposed, () => ZigZagEnemy.PoolConstructor());
            BombardEnemyPool  = new Pool <BombardEnemy>(60, true, e => !e.IsDisposed, () => BombardEnemy.PoolConstructor());
            Dual45EnemyPool   = new Pool <Dual45Enemy>(60, true, e => !e.IsDisposed, () => Dual45Enemy.PoolConstructor());
            SideEnemyPool     = new Pool <SideEnemy>(10, true, e => !e.IsDisposed, () => SideEnemy.PoolConstructor());
            // Explosions
            ExplosionPool = new Pool <Visual>(100, true, v => !v.IsDisposed, () => Visual.PoolConstructor());
            // Scrap station
            ScrapStationPool = new Pool <ScrapStation>(2, true, s => !s.IsDisposed, () => ScrapStation.PoolConstructor());
            #endregion

            Players.Add(new Player());

            // Projectile pool
            for (int i = 0; i < PROJECTILE_POOL_MAX; i++)
            {
                ProjectilePool.Add(new BaseProjectile());
            }

            // Pickup pool
            for (int i = 0; i < PICKUP_MAX; i++)
            {
                PickupPool.Add(new Pickup());
            }

            // Increase the spawn delay every 5 waves
            int spawnDelayIncs = WaveNr / 5;
            for (int i = 0; i < spawnDelayIncs; i++)
            {
                SpawnDelayTimer.TimeInMS += SPAWN_DELAY_INCREASE;
            }

            // Add starting resources
            for (int i = 1; i <= startingWave; i++)
            {
                if (i < 5)
                {
                    for (int j = 0; j < Players.Count; j++)
                    {
                        Players[j].Score += 150;
                    }
                }
                else
                {
                    for (int j = 0; j < Players.Count; j++)
                    {
                        Players[j].Score += 500;
                    }
                }
                // Limit score to ~15000
                if (Players[0].Score >= 15000)
                {
                    break;
                }
            }

            // Spawn scrap station if starting wave # >=20
            if (startingWave >= 20)
            {
                SpawnScrapStation();
            }

            #region Player
            PlayerShip ps = new PlayerShip(PlayerIndex.One, new Vector2(500, 400), Players[0]);
            ps.SetPlaneType(planeType, shipName);

            // Bonus speed & shield regen
            int bonusSpeedUpgrades = startingWave / 10;
            for (int i = 0; i < bonusSpeedUpgrades; i++)
            {
                ps.UpgradeSpeed();
                ps.UpgradeShieldRegen();
            }
            // Add mg
            MG1 mg = MGPool.New();
            mg.Initialize(new Vector2(5, ps.Height - 20), new Vector2(ps.Width - 5 - 8, ps.Height - 20), ps.Owner);
            ps.Guns.Add(mg);

            Entities.Add(ps);
            PlayerShips.Add(ps);
            #endregion

            // Pause
            PauseLocation = Common.CenterString(PausedFont, PAUSE_TEXT, Engine.Instance.Width, Engine.Instance.Height);

            // Collect Garbage
            System.GC.Collect();
        }