スケールモード

2023-06-19

スケールモードはない

ゲーム開発フレームワークには「固定サイズでゲームを作っておき、画面サイズに合わせていい感じにリサイズしてくれる」機能があります。

例えばSpriteKit の scaleModePhaser3 の ScaleManagerを使えば、簡単に実現できます。

残念ながら Flame には現状この機能がないようで、Issue 上でのやりとりを見る限り、当面実装されない気配です。

この機能がないと複数画面サイズの対応が大変になるので、 PositionComponentscaleFlameGameonGameResizeを使って擬似的に実装してみます。

公式ドキュメント https://docs.flame-engine.org/latest/flame/components.html#scale
公式ドキュメント https://docs.flame-engine.org/latest/flame/components.html#component-lifecycle
APIリファレンス https://pub.dev/documentation/flame/latest/components/PositionComponent/scale.html
APIリファレンス https://pub.dev/documentation/flame/latest/game/FlameGame/onGameResize.html

動かす

まずはゲーム本体となるPositionComponentを固定サイズで用意します。 今回はわかりやすく枠を描画するためRectangleComponentを使います。

  final _content = RectangleComponent(
    size: Vector2(360, 640),
    paint: Paint()
      ..color = Colors.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2,
  );

onGameResizeではゲームサイズ(=画面サイズ)に合わせてscaleを変更します。 リサイズ時の挙動を変えたい場合はここの動作を変えれば OK です。 例えば画面一杯に拡大したい場合などもあるでしょう。

  @override
  void onGameResize(Vector2 size) {
    final scale = size.y / _content.size.y;
    _content.scale = Vector2.all(scale);
    _content.position = Vector2(
      size.x * 0.5 - _content.size.x * 0.5 * scale,
      0,
    );
    super.onGameResize(size);
  }

これで準備は整いました。

あとはコンポーネントをゲームではなく_contentaddします。 位置の計算などにもgame.sizeではなく_content.sizeを使います。

    await _content.add(
      TextComponent(
        text: 'ScaleMode',
        textRenderer: TextPaint(
          style: TextStyle(
            color: BasicPalette.white.color,
            fontSize: 48,
          ),
        ),
        position: Vector2(_content.size.x * 0.5, _content.size.y * 0.5),
        anchor: Anchor.center,
      ),
    );

これで画面サイズに応じてコンテンツが拡大・縮小されるようになりました。

© 2023 tnantoka