Flutter Flameでシーン(Router World)の切り替え方法まとめ
Flutter Flame でゲーム制作をする時に役立つのが Router だ。
今回は、このRouterの処理を解説する。
FlameにおけるRouter , Worldとは何か?
他のゲームエンジン、ライブラリで言うところの以下のものになる。
- Router → SceneManager シーンマネージャー
- World → Scene シーン
他のゲームエンジン同様、 RouterComponentではシーン(World)をstackとして積んでいく。
実際にコードを見ていく。
以下の例ではTitleScene
とGameScene
を作成している。
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GameWidget(game: SampleGame());
}
}
class SampleGame extends FlameGame {
late final RouterComponent router;
@override
Future<void> onLoad() async {
super.onLoad();
// デフォルトでは、Vectorなどの位置関係が、中央を基準にしている。
// 例えば、 Vector2(100, 200) と指定した時に、中央から x: 100 y 200 の位置が指定される。
// Anchor.topLeftと指定することで、左上を基準にできる。
camera.viewfinder.anchor = Anchor.topLeft;
await add(
router = RouterComponent(
routes: {
'title': WorldRoute(TitleScene.new),
'game': WorldRoute(GameScene.new),
// maintainState: デフォルトで true。
// true : 1ど構築したworldを維持し続ける。
// false: worldが呼ばれるたびにworldを再構築する
'level2': WorldRoute(MyWorld2.new, maintainState: false),
},
initialRoute: 'title',
),
);
}
}
そして、実際のWorldでは以下のように定義する。
class TitleScene extends World with TapCallbacks, HasGameReference<SampleGame> {
@override
Future<void> onLoad() async {
super.onLoad();
// いろいろなComponentを定義する。ここではテキストを定義しよう。
await add(
TextComponent(
text: 'Title Scene',
position: Vector2(100, 200),
// anchor: Anchor.center,
textRenderer: TextPaint(
style: const TextStyle(fontSize: 32, color: Colors.white),
),
),
);
}
@override
bool onTapDown(TapDownEvent event) {
// game sceneに遷移する。
game.router.pushReplacementNamed('game');
// game.router.pop();
// game.router.pushReplacementNamed("game");
return true;
}
}
HasGameReference
はFlameが用意しているMixInで、
Worldオブジェクトにgame
プロパティを追加してくれる。
game
プロパティがrouterオブジェクトを持っているので、
HasGameReference
を使うとroute処理がしやすくなる。
HasGameRef
というMixInもあるが、version 1.30.1 では、deprecated(非推奨)になっている。
RouterによるWorldの遷移方法
Routerでworldを遷移するには以下の方法がある。
router.pushReplacementNamed('game');
game.router.pushReplacementNamed("game");
game.router.pop();
シンプルで覚えやすい。
参考文献
公式ドキュメントぐらいしかない。悲しい。
- 公式ドキュメント: RouterComponent — Flame