diff --git a/lib/flame/ricochlime_game.dart b/lib/flame/ricochlime_game.dart index f685185..aac8f80 100644 --- a/lib/flame/ricochlime_game.dart +++ b/lib/flame/ricochlime_game.dart @@ -438,8 +438,7 @@ class RicochlimeGame extends Forge2DGame /// Moves the existing monsters down and spawns new ones at the top Future spawnNewMonsters() async { - const monsterMoveSeconds = 1; - const monsterMoveDuration = Duration(seconds: monsterMoveSeconds); + const monsterMoveDuration = Duration(seconds: 1); state.value = GameState.monstersMoving; @@ -465,12 +464,12 @@ class RicochlimeGame extends Forge2DGame } // wait for the monsters to move - var elapsedSeconds = 0.0; - await for (final tick in ticker.onTick) { - if (inputCancelled) return; - elapsedSeconds += tick; - if (elapsedSeconds >= monsterMoveSeconds) break; - } + await ticker.delayed( + monsterMoveDuration, + onTick: () => + inputCancelled ? TickerDelayedInstruction.stopEarly : null, + ); + if (inputCancelled) return; // check if the player has lost if (isGameOver()) { diff --git a/lib/flame/ticker.dart b/lib/flame/ticker.dart index e7b3e9b..883b6f5 100644 --- a/lib/flame/ticker.dart +++ b/lib/flame/ticker.dart @@ -23,12 +23,28 @@ class Ticker { /// The actual time may be slightly longer than the given /// [duration] since it is rounded to the next tick. /// - /// Returns the elapsed time in seconds. - Future delayed(Duration duration) async { + /// If [onTick] is provided, it will be called for each tick, + /// including the final tick when the duration is reached/passed. + /// Return [TickerDelayedInstruction.stopEarly] in [onTick] to stop the + /// ticker early. + /// + /// Returns the actual elapsed time in seconds. + Future delayed( + Duration duration, { + TickerDelayedInstruction? Function()? onTick, + }) async { final durationInSeconds = duration.inMilliseconds / 1000; var elapsed = 0.0; - await for (final dt in onTick) { + await for (final dt in this.onTick) { elapsed += dt; + + switch (onTick?.call()) { + case TickerDelayedInstruction.stopEarly: + return elapsed; + default: + break; + } + if (elapsed >= durationInSeconds) return elapsed; } throw StateError( @@ -36,3 +52,9 @@ class Ticker { ); } } + +enum TickerDelayedInstruction { + /// Return this value in [Ticker.delayed]'s `onTick` + /// to stop the ticker early. + stopEarly, +}