根據 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 內的文件