Flutter × Flameで作る!世界と繋がるストレス発散アプリ「Global Smash Room」 #作る
こんにちは!今回は、FlutterとゲームエンジンFlameを使って開発した、Webブラウザで遊べる物理演算パズルアクション(?)アプリ 「Global Smash Room」 を紹介します。
ただ箱を壊すだけではありません。あなたの破壊活動は、世界中のユーザーとリアルタイムで共有されます。
🎮 アプリ概要
Global Smash Room は、画面をタップして出現させたオブジェクトを、物理演算によって破壊しまくるストレス発散ゲームです。
プラットフォーム: Web (PC/SP対応)
画面をタップすると赤い箱が生まれます。さらにタップすると、箱は物理法則に従って分裂・粉砕され、飛び散ります。そして、世界中のプレイヤーが破壊した箱の総数 がリアルタイムで画面右上にカウントアップされていきます。
🛠 技術スタック
このアプリは以下の技術で作られています。
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