根據 Flutter 原開發團隊成員 Filip所提及的
原先 Flutter 跨平台的目的其實有一部份是為了製作遊戲
而 Filip 也在遊戲製作的示範影片中
為我們展示了 Flutter 開發遊戲的魅力
Flame
所以我們今天要來介紹的是 Flame 一個 2D 的遊戲引擎
而它是以 Flutter 為基底所打造的遊戲引擎
提供了我們簡單、有效率的遊戲實作方式
而大多數我們需要製作遊戲所需使用到的輸入輸出控制、圖片資源以及動畫呈現...等
皆可以由 Flame Component System(FCS) 所提供
在音檔及圖檔的部分可透過 Flutter 匯入 assets 的方式來進行pubspec.yaml
void main() {
  FlameAudio.play('explosion.mp3');
  Flame.images.load('player.png');
  Flame.images.load('enemy.png');
}
flutter:
  assets:
    - assets/audio/explosion.mp3
    - assets/images/player.png
    - assets/images/enemy.png
GameWidget 可以用來將 Game 涵蓋進 Flutter Widget 樹內
讓我們來看一下範例程式碼
void main() {
  final game = MyGame();
  runApp(GameWidget(game: game));
}
class MyGamePage extends StatefulWidget {
  @override
  State createState() => _MyGamePageState();
}
class _MyGamePageState extends State<MyGamePage> {
  late final MyGame _game;
  
  @override
  void initState() {
    super.initState();
    _game = MyGame();
  }
  @override
  Widget build(BuildContext context) {
    return GameWidget(game: _game);
  }
}
若是透過 Stateless Widget
則可以透過 gameFactory 來將遊戲插入進 Widget 樹
class MyGamePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GameWidget.controlled(gameFactory: MyGame.new);
  }
}
該 Widget 是在 Flame 中最常被使用到的 Game 類別
而在這個 Widget 我們可以根據生命週期新增/修改/刪除物件
/// A component that renders the crate sprite, with a 16 x 16 size.
class MyCrate extends SpriteComponent {
  MyCrate() : super(size: Vector2.all(16));
  @override
  Future<void> onLoad() async {
    sprite = await Sprite.load('crate.png');
  }
}
class MyGame extends FlameGame {
  @override
  Future<void> onLoad() async {
    await add(MyCrate());
  }
}
main() {
  final myGame = MyGame(children: [MyCrate]);
  runApp(
    GameWidget(
      game: myGame,
    ),
  );
}
而透過以下的生命週期圖
我們可以在對應的時間點透過函式的呼叫來修改或新增 Component

而下圖中也列出各個 Widget 間的相互關係

本次分享的為局部的內容
詳細的內容可以參考 Flame 內的文件