Flutter × Flameで作る!世界と繋がるストレス発散アプリ「Global Smash Room」 #作る


こんにちは!今回は、FlutterとゲームエンジンFlameを使って開発した、Webブラウザで遊べる物理演算パズルアクション(?)アプリ 「Global Smash Room」 を紹介します。


ただ箱を壊すだけではありません。あなたの破壊活動は、世界中のユーザーとリアルタイムで共有されます。


🎮 アプリ概要

Global Smash Room は、画面をタップして出現させたオブジェクトを、物理演算によって破壊しまくるストレス発散ゲームです。



画面をタップすると赤い箱が生まれます。さらにタップすると、箱は物理法則に従って分裂・粉砕され、飛び散ります。そして、世界中のプレイヤーが破壊した箱の総数 がリアルタイムで画面右上にカウントアップされていきます。


🛠 技術スタック

このアプリは以下の技術で作られています。


  • Flutter (Web): UIフレームワーク。WebAssembly (WASM) 対応を見据えたモダンな構築。

  • Flame Engine: Flutterのためのゲームエンジン。

  • Flame Forge2D: Box2D物理エンジンをFlutterで扱うためのラッパー。重力、衝突、摩擦などをシミュレート。

  • Firebase:

    • Hosting: Webアプリの配信。

    • Cloud Firestore: 全世界の破壊数をリアルタイム同期。

    • Authentication: 匿名ログイン管理。

  • Riverpod: 状態管理。ローカルの破壊数とFirestoreのストリームをUIに接続。


💡 こだわりの実装ポイント

1. 物理演算による「破壊」の表現

Flame Forge2Dを使用し、タップされた瞬間に「親オブジェクトを削除」→「半分のサイズの小オブジェクトを複数生成」→「ランダムな力(Velocity)を与える」という処理を行っています。これにより、ガラスが割れるような爽快感を演出しています。


2. リアルタイム・グローバルカウンター

「今、世界でどれだけの箱が壊されたか」を共有するために、Cloud Firestoreを使用しています。 ただし、ユーザーが連打するたびに書き込みを行うと負荷が高すぎるため、バッチ処理を実装しました。 Timer.periodic を使用し、ローカルでカウントした破壊数を10秒ごとにまとめて FieldValue.increment でFirestoreに送信しています。


// 10秒ごとにまとめて送信する実装例


_timer = Timer.periodic(const Duration(seconds: 10), (_) => _syncToFirestore());


Future<void> _syncToFirestore() async {


  if (_pendingSmashes == 0) return;


  // ... Firestoreへバッチ書き込み ...


}


3. ゲームとUIの融合

Flameの GameWidget の上に、Flutterの通常のウィジェット(Stack, Positioned)を重ねることで、ゲーム画面そのものはCanvasで描画しつつ、スコア表示やボタンなどのUIはFlutterの便利なウィジェットツリーを活用しています。これにより、ゲーム開発とUI開発のいいとこ取りが可能です。


🚀 最後に

Flutterはアプリ開発だけでなく、Flameを組み合わせることでこうしたブラウザゲームも手軽に作ることができます。特にFirebaseとの連携は強力で、「サーバーサイドコードをほとんど書かずに」リアルタイム同期機能を実現できました。


ぜひ、リンクからアクセスして、世界の破壊数に貢献してみてください!




Created with Flutter & Flame