オーバーレイ

2023-05-03

オーバーレイ

Flame は Flutter の通常画面を表示するための、オーバーレイという仕組みがあります。 これを使うことで、例えば設定画面やモーダルなどを普通の Flutter で構築することができます。

この機能は僕が Flame の中で気に入っているものの 1 つです。
やはりこの時代 UI はリアクティブに書きたいので、素の Flutter に任せちゃおうというのはとても良いと思います。

overlayBuilderMap

オーバーレイで表示する UI は Flutter の Widget として作れば OK です。 その Widget をGameWidgetoverlayBuilderMapに登録します。

公式ドキュメント https://docs.flame-engine.org/latest/flame/overlays.html#overlays

動かす

オーバーレイとして表示する UI を用意します。 今回は半透明の背景の中央にモーダルダイアログが表示されるものにします。

OK をクリックしたらgame.overlays.removeを使ってオーバーレイを非表示にしています。

class Modal extends StatelessWidget {
  const Modal({super.key, required this.game});

  final OverlayGame game;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white.withAlpha(100),
      child: SimpleDialog(
        title: const Text('Modal'),
        children: [
          SimpleDialogOption(
            child: const Text('OK'),
            onPressed: () => game.overlays.remove('modal'),
          ),
        ],
      ),
    );
  }
}

次に GameWidget にオーバーレイを登録しておく必要があります。 今回はmodalという名前で、先程作ったModalを設定しています。 modalは他の箇所でも使うので定数にすべきでしょうが、この例では文字列で済ませています。

  @override
  Widget build(BuildContext context) {
    return GameWidget<OverlayGame>(
      game: game,
      overlayBuilderMap: {
        'modal': (_, game) => Modal(game: game),
      },
    );
  }

最後にボタンを押すとオーバーレイを表示するようにします。 なお、このボタンはbuttonDownを省略しているのでクリック中も表示が変わりません。

オーバーレイの表示overlays.addを使います。

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';

class OverlayGame extends FlameGame {
  @override
  Future<void> onLoad() async {
    super.onLoad();

    await add(
      ButtonComponent(
        position: Vector2(size.x * 0.5, size.y * 0.2),
        onPressed: () => overlays.add('modal'),
        button: TextComponent(
          text: 'Modal',
          textRenderer: TextPaint(
            style: const TextStyle(
              fontSize: 32,
              color: Colors.white,
            ),
          ),
        ),
        anchor: Anchor.center,
      ),
    );
  }
}

これで素の Flutter 製の UI が表示されるようになりました。

© 2023 tnantoka