/// <summary> /// Simulates the gameplay logic for this <see cref="EnemyGroup"/>. /// </summary> /// <param name="deltaTime">The elapsed time between this frame and the last frame, in seconds.</param> public void Update(float deltaTime) { GameplayScreen gameplayScreen = MainGame.Context.GetGameScreen <GameplayScreen>(GameScreenType.Gameplay); if (isStartupAnimation) { startupAnimationTimer -= deltaTime; if (startupAnimationTimer <= 0) { startupAnimationTimer = StartupAnimationTime; renderRowThreshold -= 1; } if (renderRowThreshold == 0) { isStartupAnimation = false; gameplayScreen.Unfreeze(); } } if (gameplayScreen.IsFrozen) { return; } timeToMovement -= deltaTime; if (timeToMovement <= 0) { if (canVerticallyMove && IsTouchingHorizontalBounds()) { movementDirection *= -1; boundingRectangle.Y += VerticalMovementShift * MainGame.ResolutionScale; canVerticallyMove = false; } else { boundingRectangle.X += HorizontalMovementShift * MainGame.ResolutionScale * movementDirection; canVerticallyMove = true; } timeToMovement = GetMovementTime(); animationFrameToggle = !animationFrameToggle; movementSounds[movementSoundCounter].Play(); movementSoundCounter = (movementSoundCounter + 1) % movementSounds.Length; } for (int x = 0; x < GroupWidth; x++) { for (int y = GroupHeight - 1; y >= 0; y--) { // Only bottom-most enemies in their respective columns can attack if (!enemyGrid[x, y].Active || y < GroupHeight - 1 && enemyGrid[x, y + 1].Active) { continue; } Enemy enemy = enemyGrid[x, y]; enemy.AttackTime -= deltaTime; if (!(enemy.AttackTime <= 0)) { continue; } enemy.AttackTime = GetEnemyAttackTime(); // If this enemy has not attacked since the start of the game, it means that // the attack time was only generated this frame; hence, let's return and // turn off the flag. if (!enemy.HasAttacked) { enemy.HasAttacked = true; return; } gameplayScreen.ProjectileController.CreateEnemyProjectile(enemy); // Since we have the bottom-most enemy that active, we are done looking // at the current column. break; } } for (int i = activeExplosions.Count - 1; i >= 0; i--) { activeExplosions[i] = new Tuple <Enemy, float>(activeExplosions[i].Item1, activeExplosions[i].Item2 - deltaTime); if (activeExplosions[i].Item2 <= 0) { activeExplosions.RemoveAt(i); } } Enemy bottomMost = GetBottomMostEnemy(); if (GetEnemyWorldRectangle(bottomMost).Bottom > gameplayScreen.BarrierGroup[0].Rectangle.Bottom) { gameplayScreen.TriggerGameover(); } }