2023-05-03
Flame は Flutter の通常画面を表示するための、オーバーレイという仕組みがあります。 これを使うことで、例えば設定画面やモーダルなどを普通の Flutter で構築することができます。
この機能は僕が Flame の中で気に入っているものの 1 つです。
やはりこの時代 UI はリアクティブに書きたいので、素の Flutter に任せちゃおうというのはとても良いと思います。
オーバーレイで表示する UI は Flutter の Widget として作れば OK です。
その Widget をGameWidget
のoverlayBuilderMap
に登録します。
オーバーレイとして表示する 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