/// <summary>
        /// Update wave, updating behavior of all enemies.
        /// Check collisions against player and self, but not other waves
        /// Check weapon collisions against player
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="player"></param>
        /// <param name="blackHole"></param>
        /// <param name="weapon1"></param>
        /// <param name="weapon2"></param>
        public void Update(GameTime gameTime, Spaceman player,
                           BlackHole blackHole, Weapon weapon1, Weapon weapon2,
                           Unicorn[] unicorns)
        {
            if (_startTimer >= TimeSpan.Zero)        //not started yet
            {
                _startTimer -= gameTime.ElapsedGameTime;
                if (_startTimer < TimeSpan.Zero)
                {
                    Active = true;                                                            //activate if start timer complete
                    setPosition(blackHole.Position, _levelBounds.Width, _levelBounds.Height); //set first spawn position
                }
            }

            if (_portalEffect != null)
            {
                _portalEffect.Update(gameTime);
            }

            if (!Active)
            {
                return;     //don't update if not active
            }
            //play particle effect if existant
            if (_portalEffect != null)
            {
                //spawn particles if still spawning enemies
                if (_spawnedSoFar < _numEnemies && SpawnEnable)
                {
                    _portalEffect.Spawn(_spawnLocation, 90.0f + _portalAngle, gameTime.ElapsedGameTime, Vector2.Zero);
                    _portalEffect.Spawn(_spawnLocation, -90.0f + _portalAngle, gameTime.ElapsedGameTime, Vector2.Zero);
                }
                _portalAngle += (float)gameTime.ElapsedGameTime.TotalSeconds * PORTAL_ROTATION_RATE;
                if (_activationDelay >= TimeSpan.Zero)      //gradually increase particle intensity
                {
                    _portalEffect.IntensityFactor = 1.0f - (float)_activationDelay.TotalSeconds / ACTIVATION_DELAY_SECONDS;
                }
            }

            //only start spawning if activation delay is elapsed.
            //Otherwise, just start particleeffect and don't spawn enemies yet
            if (_activationDelay > TimeSpan.Zero)
            {
                _activationDelay -= gameTime.ElapsedGameTime;
                return;
            }

            //run spawning logic
            spawn(gameTime, _spawnLocation, blackHole.Position);

            //update all enemies in wave
            bool allDestroyed = true;   //check if all enemies destroyed

            for (int i = _enemies.Length - 1; i >= 0; i--)
            {
                if (!_enemies[i].Updates)
                {
                    continue;         //don't update units that shouldn't be updated
                }
                allDestroyed = false; //found one that isn't destroyed

                for (int j = i - 1; j >= 0; j--)
                {
                    //check collision against other enemies in same wave
                    _enemies[i].CheckAndApplyUnitCollision(_enemies[j]);
                }

                for (int j = 0; j < unicorns.Length; j++)
                {
                    //check collision against unicorns
                    unicorns[j].CheckAndApplyCollision(_enemies[i], gameTime);
                }
                _enemies[i].CheckAndApplyUnitCollision(player);
                _enemies[i].CheckAndApplyWeaponCollision(player, gameTime.ElapsedGameTime);

                _enemies[i].Update(gameTime, player.Position, Vector2.Zero, _levelBounds);
                blackHole.ApplyToUnit(_enemies[i], gameTime);
                weapon1.CheckAndApplyCollision(_enemies[i], gameTime.ElapsedGameTime);
                weapon2.CheckAndApplyCollision(_enemies[i], gameTime.ElapsedGameTime);
            }
            //stay active unless it is not a trickle wave and all enemies are destroyed
            Active = Active && (_isTrickleWave || !allDestroyed);
        }
        /// <summary>
        /// Update wave, updating behavior of all enemies.
        /// Check collisions against player and self, but not other waves
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="player"></param>
        /// <param name="blackHole"></param>
        /// <param name="weapon1"></param>
        /// <param name="weapon2"></param>
        public void Update(GameTime gameTime, Spaceman player, 
            BlackHole blackHole, Weapon weapon1, Weapon weapon2)
        {
            if (_startTimer >= TimeSpan.Zero)        //not started yet
            {
                _startTimer -= gameTime.ElapsedGameTime;
                if (_startTimer < TimeSpan.Zero)
                {
                    Active = true;      //activate if start timer complete
                    setPosition(blackHole.Position);        //set first spawn position
                }
            }

            if (!Active)
                return;     //don't update if not active

            //play particle effect if existant
            if (_portalEffect != null)
            {
                //spawn particles if still spawning enemies
                if (_spawnedSoFar < _numEnemies)
                {
                    _portalEffect.Spawn(_spawnLocation, 90.0f + _portalAngle, gameTime.ElapsedGameTime, Vector2.Zero);
                    _portalEffect.Spawn(_spawnLocation, -90.0f + _portalAngle, gameTime.ElapsedGameTime, Vector2.Zero);
                }
                _portalAngle += (float)gameTime.ElapsedGameTime.TotalSeconds * PORTAL_ROTATION_RATE;
                _portalEffect.Update(gameTime);
                if (_activationDelay >= TimeSpan.Zero)      //gradually increase particle intensity
                {
                    _portalEffect.IntensityFactor = 1.0f - (float)_activationDelay.TotalSeconds / ACTIVATION_DELAY_SECONDS;
                }
            }

            //only start spawning if activation delay is elapsed.
            //Otherwise, just start particleeffect and don't spawn enemies yet
            if (_activationDelay > TimeSpan.Zero)
            {
                _activationDelay -= gameTime.ElapsedGameTime;
                return;
            }

            //run spawning logic
            spawn(gameTime, _spawnLocation, blackHole.Position);

            //update all enemies in wave
            bool allDestroyed = true;   //check if all enemies destroyed
            for (int i = _enemies.Length - 1; i >= 0; i--)
            {
                if (_enemies[i].UnitLifeState == PhysicalUnit.LifeState.Destroyed)
                    continue;   //don't update destroyed units

                allDestroyed = false;       //found one that isn't destroyed
                for (int j = i - 1; j >= 0; j--)
                {
                    //check collision against other enemies
                    _enemies[i].CheckAndApplyUnitCollision(_enemies[j]);
                }
                _enemies[i].CheckAndApplyUnitCollision(player);

                _enemies[i].Update(gameTime, player.Position, Vector2.Zero);
                blackHole.ApplyToUnit(_enemies[i], gameTime);
                weapon1.CheckAndApplyCollision(_enemies[i]);
                weapon2.CheckAndApplyCollision(_enemies[i]);
            }
            //stay active unless it is not a trickle wave and all enemies are destroyed
            Active = Active && (_isTrickleWave || !allDestroyed);
        }
        /// <summary>
        /// Update wave, updating behavior of all enemies.
        /// Check collisions against player and self, but not other waves
        /// Check weapon collisions against player
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="player"></param>
        /// <param name="blackHole"></param>
        /// <param name="weapon1"></param>
        /// <param name="weapon2"></param>
        public virtual void Update(GameTime gameTime, Spaceman player,
            BlackHole blackHole, Weapon weapon1, Weapon weapon2, InventoryManager inventory, Unicorn[] unicorns)
        {
            if (!Active) { return; }

            //update all enemies in wave
            bool allDestroyed = true;   //check if all enemies destroyed
            for (int i = _bodies.Length - 1; i >= 0; i--)
            {
                if (_bodies[i].UnitLifeState != PhysicalBody.LifeState.Destroyed)
                {
                    allDestroyed = false;       //found one that isn't destroyed
                }

                if (!_bodies[i].Updates)
                    continue;   //don't update units that shouldn't be updated

                for (int j = i - 1; j >= 0; j--)
                {
                    //check collision against other enemies in same wave
                    _bodies[i].CheckAndApplyUnitCollision(_bodies[j]);
                    if (_bodies[i] is Obstacle)
                    {
                        (_bodies[i] as Obstacle).CheckAndApplyEffect(_bodies[j], gameTime.ElapsedGameTime);
                    }
                }

                for (int j = 0; j < unicorns.Length; j++)
                {
                    //check collision against unicorns
                    unicorns[j].CheckAndApplyCollision(_bodies[i], gameTime);
                }

                _bodies[i].CheckAndApplyUnitCollision(player);

                if (_bodies[i] is Enemy)
                {
                    (_bodies[i] as Enemy).CheckAndApplyWeaponCollision(player, gameTime.ElapsedGameTime);
                    (_bodies[i] as Enemy).Update(gameTime, player.Position, blackHole, _levelBounds);
                }
                else
                {
                    (_bodies[i] as Obstacle).Update(gameTime, _levelBounds);
                    (_bodies[i] as Obstacle).CheckAndApplyEffect(player, gameTime.ElapsedGameTime);
                }

                blackHole.ApplyToUnit(_bodies[i], gameTime);
                if (weapon1 != null)
                {
                    weapon1.CheckAndApplyCollision(_bodies[i], gameTime.ElapsedGameTime);
                }
                if (weapon2 != null)
                {
                    weapon2.CheckAndApplyCollision(_bodies[i], gameTime.ElapsedGameTime);
                }
                inventory.CheckCollisions(gameTime, _bodies[i]);
            }

            trySpawnObstacle(gameTime.ElapsedGameTime, blackHole.Position);

            _allDestroyed = allDestroyed;
        }