【Flame 學習筆記】 FlameGame:建立基於元件的遊戲架構

更新於 發佈於 閱讀時間約 11 分鐘
raw-image
【Flame 學習筆記】系列文章目錄:連結
【Flutter 學習筆記】線上課程教學影片:連結
【Flutter 學習筆記】系列文章目錄:連結

在這篇文章中,我們將深入探討 Flutter 的 Flame 遊戲引擎中的 FlameGame 類別,並了解其如何實現一個基於元件的遊戲架構。這個架構稱為 Flame 元件系統(Flame Component System,簡稱 FCS),它透過一棵元件樹來管理遊戲中的所有元件,並負責調用這些元件的更新和渲染方法。

FlameGame 類別概述

FlameGame 類別是 Flame 引擎的核心,允許開發者透過構造函數中的 children 參數直接添加元件,或使用 addaddAll 方法在其他地方添加元件。通常,我們會將元件添加到一個名為 World 的預設世界中,這個世界可以透過 FlameGame.world 訪問,並且添加元件的方式與其他元件相同。

以下是一個簡單的 FlameGame 實作範例,展示如何在 onLoad 方法中和構造函數中添加兩個元件:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/widgets.dart';

/// 一個渲染箱子精靈的元件,大小為 16 x 16。
class MyCrate extends SpriteComponent {
MyCrate() : super(size: Vector2.all(16));

@override
Future<void> onLoad() async {
sprite = await Sprite.load('crate.png');
}
}

class MyWorld extends World {
@override
Future<void> onLoad() async {
await add(MyCrate());
}
}

void main() {
final myGame = FlameGame(world: MyWorld());
runApp(
GameWidget(game: myGame),
);
}

注意事項

如果你在 build 方法中實例化遊戲,則每當 Flutter 樹重建時,遊戲也會被重建,這通常會比你預期的更頻繁。為了避免這種情況,你可以先創建遊戲的實例,然後在小部件結構中引用它,或者使用 GameWidget.controlled 構造函數。

遊戲循環

GameLoop 模組是遊戲循環概念的一個簡單抽象。大多數遊戲都基於兩個方法:

  • render 方法用於繪製當前遊戲狀態的畫布。
  • update 方法接收自上次更新以來的微秒數,並允許你移動到下一個狀態。

GameLoop 被所有 Flame 的遊戲實作所使用。

調整大小

每當遊戲需要調整大小時,例如當方向改變時,FlameGame 會調用所有元件的 onGameResize 方法,並將此信息傳遞給相機和視口。FlameGame.camera 控制應該在視口中心的坐標點,預設為 [0,0](Anchor.center)。

生命週期

FlameGame 的生命週期回調(如 onLoadrender 等)按以下順序被調用:

raw-image
  1. 每個 Tick 運行
  2. 添加和調整大小時運行
  3. 只運行一次
  4. 如果被移除
  5. 如果重新父化
  6. onGameResize
  7. onLoad
  8. onMount
  9. update
  10. render
  11. onRemove

FlameGame 首次添加到 GameWidget 時,生命週期方法 onGameResizeonLoadonMount 將按此順序被調用。然後,updaterender 將在每個遊戲 Tick 中按序列被調用。如果 FlameGameGameWidget 中移除,則會調用 onRemove。如果 FlameGame 被添加到新的 GameWidget,則序列將從 onGameResize 重複。

注意事項

onGameResizeonLoad 的調用順序與其他元件相反,這是為了在資源加載或生成之前計算遊戲元素的大小。

onRemove 回調可用於清理子元件和緩存數據:

@override
void onRemove() {
// 根據遊戲需求選擇性執行。
removeAll(children);
processLifecycleEvents();
Flame.images.clearCache();
Flame.assets.clearCache();
// 在遊戲被移除時執行的其他代碼。
}

注意事項

FlameGame 中,子元件和資源的清理並不會自動進行,必須明確添加到 onRemove 回調中。

除錯模式

Flame 的 FlameGame 類別提供了一個名為 debugMode 的變數,預設為 false。不過,你可以將其設置為 true 以啟用遊戲元件的除錯功能。請注意,這個變數的值會在元件添加到遊戲時傳遞,因此如果你在運行時更改 debugMode,則不會影響已添加的元件。

有關 debugMode 的更多資訊,請參考 Flame 的除錯文檔。

更改背景顏色

要更改 FlameGame 的背景顏色,你需要重寫 backgroundColor() 方法。在以下範例中,背景顏色被設置為完全透明,以便可以看到 GameWidget 背後的元件。預設背景顏色為不透明的黑色。

class MyGame extends FlameGame {
@override
Color backgroundColor() => const Color(0x00000000);
}

請注意,背景顏色在遊戲運行時無法動態更改,但如果你希望它動態變化,可以繪製一個覆蓋整個畫布的背景。

單一遊戲實例混入

如果你正在開發一個單一遊戲應用程式,可以選擇性地將 SingleGameInstance 混入應用於你的遊戲。這在構建遊戲時是一個常見的場景:有一個全螢幕的 GameWidget,其中只包含一個遊戲實例。

添加這個混入可以在某些情況下提供性能優勢。特別是,元件的 onLoad 方法在元件添加到其父元件時保證會開始執行,即使父元件尚未掛載。因此,對 parent.add(component)await 將始終保證完成元件的加載。

使用這個混入非常簡單:

class MyGame extends FlameGame with SingleGameInstance {
// ...
}

低階遊戲 API

raw-image

Game 類別是一個低階 API,當你想要實現遊戲引擎的結構功能時可以使用。Game 類別不實現任何更新或渲染功能。

這個類別還包含生命週期方法 onLoadonMountonRemove,這些方法在遊戲被加載、掛載或移除時由 GameWidget(或其他父元件)調用。onLoad 只在類別第一次添加到父元件時被調用,而 onMount(在 onLoad 之後被調用)則在每次添加到新父元件時被調用。onRemove 在類別從父元件移除時被調用。

注意事項

使用 Game 類別可以提供更大的實現自由度,但如果使用它,你將錯過 Flame 中的所有內建功能。

以下是一個 Game 實作的範例:

class MyGameSubClass extends Game {
@override
void render(Canvas canvas) {
// ...
}

@override
void update(double dt) {
// ...
}
}

void main() {
final myGame = MyGameSubClass();
runApp(
GameWidget(
game: myGame,
)
);
}

暫停/恢復/逐步執行遊戲

Flame 遊戲可以通過以下兩種方式暫停和恢復:

  1. 使用 pauseEngine 和 resumeEngine 方法。
  2. 通過更改 paused 屬性。

當遊戲被暫停時,遊戲循環將被有效地暫停,這意味著在恢復之前不會進行任何更新或新的渲染。在遊戲暫停期間,可以使用 stepEngine 方法逐幀推進遊戲執行。這在最終遊戲中可能不太有用,但在開發過程中逐步檢查遊戲狀態時非常有幫助。

背景處理

當應用程式被送到背景時,遊戲將自動暫停,並在應用程式回到前景時恢復。這種行為可以通過將 pauseWhenBackgrounded 設置為 false 來禁用。

class MyGame extends FlameGame {
MyGame() {
pauseWhenBackgrounded = false;
}
}

在當前的 Flutter 穩定版本(3.13)中,這個標誌在非移動平台(包括網頁)上實際上會被忽略。

性能追蹤混入

在優化遊戲時,追蹤每幀更新和渲染所需的時間可能會很有用。這些數據可以幫助檢測代碼中運行較快的區域,並幫助識別渲染時間較長的視覺區域。

要獲取更新和渲染時間,只需將 HasPerformanceTracker 混入添加到遊戲類別中。

class MyGame extends FlameGame with HasPerformanceTracker {
// 可以訪問 `updateTime` 和 `renderTime` 屬性。
}

總結

在這篇文章中,我們深入探討了 Flame 遊戲引擎中的 FlameGame 類別及其元件系統。透過這個系統,開發者可以輕鬆地管理遊戲中的元件,並利用遊戲循環、生命週期回調、除錯模式等功能來構建高效的遊戲應用。


留言
avatar-img
留言分享你的想法!
avatar-img
HKT實驗室
24會員
261內容數
哈囉!歡迎光臨我的沙龍!我是 KT,一位對應用程式開發充滿熱情的開發者。在這個專屬空間,我將與您分享我在應用開發領域的深入學習心得和豐富的實戰經驗。如果您對應用程式開發技術同樣充滿好奇,渴望不斷探索新知,歡迎成為我們的會員,一起在應用程式開發的旅途上,探索更深層次的技術世界,享受學習的樂趣。
HKT實驗室的其他內容
2024/11/13
本篇文章介紹 GameWidget 是 Flutter 中用於嵌入遊戲實例的 widget,能作為應用程式的根部件或嵌入其他 widget 中。它自動擴展以填滿可用空間,並提供多種結構支援功能,如加載、錯誤處理和背景裝飾。
Thumbnail
2024/11/13
本篇文章介紹 GameWidget 是 Flutter 中用於嵌入遊戲實例的 widget,能作為應用程式的根部件或嵌入其他 widget 中。它自動擴展以填滿可用空間,並提供多種結構支援功能,如加載、錯誤處理和背景裝飾。
Thumbnail
2024/11/13
本文介紹 Flame 遊戲引擎建議的專案結構包含標準的 Flutter 資源目錄,並新增音效(audio)、圖片(images)和磚塊(tiles)子目錄。開發者需在 pubspec.yaml 中註冊資源,並可選擇自訂資源結構,使用 AssetsCache 和 Images 來管理資源位置。
Thumbnail
2024/11/13
本文介紹 Flame 遊戲引擎建議的專案結構包含標準的 Flutter 資源目錄,並新增音效(audio)、圖片(images)和磚塊(tiles)子目錄。開發者需在 pubspec.yaml 中註冊資源,並可選擇自訂資源結構,使用 AssetsCache 和 Images 來管理資源位置。
Thumbnail
2024/11/13
本文介紹 Flame 是一個模組化的 Flutter 遊戲引擎,提供簡單的遊戲循環和多種功能,如輸入處理、圖像管理和碰撞檢測。對於需要網路功能的多人遊戲,推薦使用 Nakama、Firebase 或 Supabase 等服務。
Thumbnail
2024/11/13
本文介紹 Flame 是一個模組化的 Flutter 遊戲引擎,提供簡單的遊戲循環和多種功能,如輸入處理、圖像管理和碰撞檢測。對於需要網路功能的多人遊戲,推薦使用 Nakama、Firebase 或 Supabase 等服務。
Thumbnail
看更多
你可能也想看
Thumbnail
沙龍一直是創作與交流的重要空間,這次 vocus 全面改版了沙龍介面,就是為了讓好內容被好好看見! 你可以自由編排你的沙龍首頁版位,新版手機介面也讓每位訪客都能更快找到感興趣的內容、成為你的支持者。 改版完成後可以在社群媒體分享新版面,並標記 @vocus.official⁠ ♥️ ⁠
Thumbnail
沙龍一直是創作與交流的重要空間,這次 vocus 全面改版了沙龍介面,就是為了讓好內容被好好看見! 你可以自由編排你的沙龍首頁版位,新版手機介面也讓每位訪客都能更快找到感興趣的內容、成為你的支持者。 改版完成後可以在社群媒體分享新版面,並標記 @vocus.official⁠ ♥️ ⁠
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
本章介紹了 FlameGame 類別,強調其基於元件的架構(Flame Component System,FCS)。FlameGame 允許開發者透過構造函數或方法添加元件,並管理遊戲的更新和渲染。文章涵蓋了遊戲循環、生命週期回調、除錯模式、背景處理及性能追蹤等功能,幫助開發者有效構建遊戲應用。
Thumbnail
本章介紹了 FlameGame 類別,強調其基於元件的架構(Flame Component System,FCS)。FlameGame 允許開發者透過構造函數或方法添加元件,並管理遊戲的更新和渲染。文章涵蓋了遊戲循環、生命週期回調、除錯模式、背景處理及性能追蹤等功能,幫助開發者有效構建遊戲應用。
Thumbnail
本篇文章介紹 GameWidget 是 Flutter 中用於嵌入遊戲實例的 widget,能作為應用程式的根部件或嵌入其他 widget 中。它自動擴展以填滿可用空間,並提供多種結構支援功能,如加載、錯誤處理和背景裝飾。
Thumbnail
本篇文章介紹 GameWidget 是 Flutter 中用於嵌入遊戲實例的 widget,能作為應用程式的根部件或嵌入其他 widget 中。它自動擴展以填滿可用空間,並提供多種結構支援功能,如加載、錯誤處理和背景裝飾。
Thumbnail
本文介紹 Flame 遊戲引擎建議的專案結構包含標準的 Flutter 資源目錄,並新增音效(audio)、圖片(images)和磚塊(tiles)子目錄。開發者需在 pubspec.yaml 中註冊資源,並可選擇自訂資源結構,使用 AssetsCache 和 Images 來管理資源位置。
Thumbnail
本文介紹 Flame 遊戲引擎建議的專案結構包含標準的 Flutter 資源目錄,並新增音效(audio)、圖片(images)和磚塊(tiles)子目錄。開發者需在 pubspec.yaml 中註冊資源,並可選擇自訂資源結構,使用 AssetsCache 和 Images 來管理資源位置。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
完成了Debug.log()的測試,接著還是要跟各位簡單講一下C#的一些規則,之後看程式會(比較)看得懂。 又講到變數? 在Unity中,變數是重要的工具,用來儲存和管理資料。讓開發者能夠靈活調整遊戲的行為和性能,減少代碼的重複性,使得遊戲開發更加高效和簡潔。透過使用變數,開發者可以輕鬆修改資料
Thumbnail
完成了Debug.log()的測試,接著還是要跟各位簡單講一下C#的一些規則,之後看程式會(比較)看得懂。 又講到變數? 在Unity中,變數是重要的工具,用來儲存和管理資料。讓開發者能夠靈活調整遊戲的行為和性能,減少代碼的重複性,使得遊戲開發更加高效和簡潔。透過使用變數,開發者可以輕鬆修改資料
Thumbnail
這篇文章將會講述使用 C# 的類( Class ) 來讓欄位模組(module)化。
Thumbnail
這篇文章將會講述使用 C# 的類( Class ) 來讓欄位模組(module)化。
Thumbnail
在 RMMV 中的功能達不到我要的效果怎麼辦?那麼就來使用插件擴展功能!這篇會跟大家講解「插件」,並且推薦想要了解 RMMV 架構的人一些講座。
Thumbnail
在 RMMV 中的功能達不到我要的效果怎麼辦?那麼就來使用插件擴展功能!這篇會跟大家講解「插件」,並且推薦想要了解 RMMV 架構的人一些講座。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News