gameLoop function

Future<void> gameLoop(
  1. void update(
    1. Screen,
    2. BufferedKeys
    ), {
  2. Duration framesPerSecond = const Duration(milliseconds: 1000 ~/ 30),
  3. void onStart(
    1. Screen
    )?,
})

Runs a game loop, which invokes update on every frame.

Implementation

Future<void> gameLoop(
  void Function(Screen, BufferedKeys) update, {
  Duration framesPerSecond = const Duration(milliseconds: 1000 ~/ 30),
  void Function(Screen)? onStart,
}) async {
  stdin.setRawMode(true);

  final display = Display.fromAnsiTerminal(
    stdout,
    width: () => stdout.terminalColumns,
    height: () => stdout.terminalLines,
  );
  final screen = Screen.display(display);

  if (onStart != null) {
    onStart(screen);
  }

  final keys = BufferedKeys.async(stdin);

  var isRunning = true;
  await for (final void _ in Stream.periodic(framesPerSecond)) {
    try {
      update(screen, keys);
      screen.update();

      // Universal quit for ESC.
      if (keys.isPressed(27)) {
        isRunning = false;
        stderr.writeln('ESC: Exiting...');
      }

      keys.clear();
    } on Object catch (e, s) {
      stderr
        ..writeln('Unhandled exception: $e')
        ..writeln(Trace.from(s).terse);
      isRunning = false;
    }
    if (!isRunning) {
      stdin.setRawMode(false);
      keys.cancel();
      break;
    }
  }
}