onLoad method

  1. @override
FutureOr<void> onLoad()
override

Late initialization method for Component.

Usually, this method is the main place where you initialize your component. This has several advantages over the traditional constructor:

  • this method can be async;
  • it is invoked when the size of the game canvas is already known.

If your loading logic requires knowing the size of the game canvas, then add HasGameRef mixin and then query game.size or game.canvasSize.

The default implementation returns null, indicating that there is no need to await anything. When overriding this method, you have a choice whether to create a regular or async function.

If you need an asynchronous onLoad, make your override return non-nullable Future<void>:

@override
Future<void> onLoad() async {
  // your code here
}

Alternatively, if your onLoad function doesn't use any awaiting, then you can declare it as a regular method returning void:

@override
void onLoad() {
  // your code here
}

The engine ensures that this method will be called exactly once during the lifetime of the Component object. Do not call this method manually.

Implementation

@override
FutureOr<void> onLoad() async {
  if (area == null && !selfPositioning) {
    final parentPosition =
        ancestors().whereType<PositionProvider>().firstOrNull?.position ??
            Vector2.zero();
    final parentSize =
        ancestors().whereType<ReadOnlySizeProvider>().firstOrNull?.size ??
            Vector2.zero();
    assert(
      !parentSize.isZero(),
      'The SpawnComponent needs an ancestor with a size if area is not '
      'provided.',
    );
    area = Rectangle.fromLTWH(
      parentPosition.x,
      parentPosition.y,
      parentSize.x,
      parentSize.y,
    );
  }

  void updatePeriod() {
    if (hasRandomPeriod) {
      period = minPeriod! + _random.nextDouble() * (maxPeriod! - minPeriod!);
    }
  }

  updatePeriod();

  final timerComponent = TimerComponent(
    period: _period,
    repeat: true,
    onTick: () {
      final component = factory(amount);
      if (!selfPositioning) {
        component.position = area!.randomPoint(
          random: _random,
          within: within,
        );
      }
      parent?.add(component);
      updatePeriod();
      amount++;
    },
    autoStart: autoStart,
    tickWhenLoaded: spawnWhenLoaded,
  );
  timer = timerComponent.timer;
  add(timerComponent);
}