Work in progress

The content of this page was not yet updated for Godot 4.2 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

匯出自訂 HTML 頁面

雖然 Web 匯出範本提供了一個預設的 HTML 頁面,完全能夠在沒有任何進一步定制的情況下啟動專案,但建立自訂 HTML 頁面可能是有益的。雖然遊戲本身還不能輕易地從外部直接控制,但這樣的頁面允許自訂引擎的初始化過程。

自訂預設頁面在某些情況下非常有用,包括:

  • 讀取與該頁面不同目錄下的檔;

  • 載入 .zip 檔而不是 .pck 檔案作為主資源包;

  • 從主資源包檔以外的目錄中載入引擎檔;

  • 新增“點擊開始”按鈕,使遊戲可以在全螢幕模式下啟動;

  • 在引擎啟動之前載入一些額外的檔,以便稍後在檔案系統中可用;

  • 傳遞自訂 "命令列" 參數, 例如 -s 啟動 MainLoop 腳本.

預設的HTML頁面可在Godot引擎倉庫 /misc/dist/html/full-size.html 中找到, 但以下範本可作為一個更簡單的例子:

<!DOCTYPE html>
<html>
    <head>
        <title>My Template</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <canvas id="canvas"></canvas>
        <script src="$GODOT_URL"></script>
        <script>
            var engine = new Engine($GODOT_CONFIG);
            engine.startGame();
        </script>
    </body>
</html>

設定

如上面的例子所示,它主要是一個普通的HTML文件,有幾個預留位置需要在匯出時替換,一個html <canvas> 元素,和一些簡單的JavaScript程式碼,呼叫 Engine() 類。

型別預留位置

  • $GODOT_URL : 主JavaScript檔的名稱,它提供了啟動引擎所需的 Engine() 類,必須作為 <script> 包含在HTML中。這個名字是在匯出過程中從*匯出路徑Export Path* 生成的。

  • $GODOT_CONFIG : 一個JavaScript物件,包含匯出選項,以後可以被重寫。參見 EngineConfig 獲取完整的重寫列表。

以下可選的預留位置將在你的自訂 HTML 範本中實作一些額外的功能。

  • $GODOT_PROJECT_NAME: 在專案設定中定義的專案名稱。在你的範本中使用它作為 <title> 是一個好主意。

  • $GODOT_HEAD_INCLUDE. 在HTML檔中, 在 <head> 標籤結尾前包含的一個自訂字串. 它是在*Html / Head Include*部分的匯出選項中自訂的. 雖然你可以完全控制你所建立的HTML頁面, 但這個變數對於從Godot Editor中配置HTML``head`` 元素的部分內容很有用, 例如, 對於不同的Web匯出預設.

當自訂頁面準備好後, 可以在 Html / Custom Html Shell 部分的匯出選項中選擇.

../../../_images/html5_export_options.png

建立內容

為了能夠啟動遊戲,你需要寫一個腳本來初始化引擎 — 控制程式碼。這個過程包括三個步驟,不過如圖所示,其中大部分步驟可以跳過,這取決於需要多少定制化的內容,或者留給預設行為。

參見 HTML5 shell 類參考,以獲得可用方法和選項的完整列表。

首先,引擎必須被載入,然後需要被初始化,在這之後,專案最終可以被啟動。你可以手動執行這些步驟中的每一步,而且控制得很好。然而,在最簡單的情況下,你需要做的是用匯出的配置建立一個 Engine() 類的實例,然後呼叫 engine.startGame 方法,可選擇重寫任何 EngineConfig 參數。

const engine = new Engine($GODOT_CONFIG);
engine.startGame({
    /* optional override configuration, eg. */
    // unloadAfterInit: false,
    // canvasResizePolicy: 0,
    // ...
});

這段程式碼在啟動遊戲前自動載入和初始化引擎。它使用給定的配置來載入引擎。engine.startGame 方法是非同步的,返回一個 Promise。這允許你的控制程式碼追蹤遊戲是否被正確載入,而無需阻塞執行或依賴輪詢。

如果你的專案需要對啟動參數和依賴檔進行特別控制,可以使用 engine.start 方法來代替。注意,這個方法不會自動預載入 pck 檔,所以你可能要通過 engine.preloadFile 方法手動預載入它和任何其他額外的檔案。

另外,你也可以手動 engine.init 在模組初始化之後,但在引擎啟動之前,執行特定的動作。

這個過程有點複雜,但可以讓你完全控制引擎的啟動過程。

const myWasm = 'mygame.wasm';
const myPck = 'mygame.pck';
const engine = new Engine();
Promise.all([
    // Load and init the engine
    engine.init(myWasm),
    // And the pck concurrently
    engine.preloadFile(myPck),
]).then(() => {
    // Now start the engine.
    return engine.start({ args: ['--main-pack', myPck] });
}).then(() => {
    console.log('Engine has started!');
});

要手動載入引擎,必須呼叫 Engine.load() 靜態方法。由於這個方法是靜態的,如果多個引擎實例共用相同的 wasm ,就可以產生多個引擎實例。

備註

預設情況下不能生成多個實例,因為引擎被初始化後會立即解除安裝。為了防止這種情況發生,請看 unloadAfterInit 覆蓋選項。之後仍然可以通過呼叫 Engine.unload() 靜態方法來手動解除安裝引擎。解除安裝引擎可以通過解除安裝實例初始化後不再需要的檔來釋放瀏覽器記憶體。

自訂行為

在 Web 環境下,可以使用幾種方法來保證遊戲能夠按照預期的方式運作。

如果您的目標是 WebGL 的特定版本,或者只是想檢查 WebGL 是否可用,您可以呼叫 Engine.isWebGLAvailable() 方法。它可以選擇接受一個參數,允許測試 WebGL 的特定主要版本。

由於真正的可執行檔不存在於 Web 環境中,引擎只儲存一個由載入的引擎檔的基本名稱形成的虛擬檔案名。這個值會影響 OS.get_executable_path() 方法的輸出,並定義自動啟動的主包的名稱。executable 選項可以用來重寫這個值。

自訂展現形式

有幾個配置選項可以用來進一步定制你頁面上遊戲的外觀和行為。

預設情況下會使用頁面上的第一個 canvas 元素來渲染。要使用其他 canvas 元素,可以使用 canvas 選項重寫。它需要一個對 DOM 元素本身的引用。

const canvasElement = document.querySelector("#my-canvas-element");
engine.startGame({ canvas: canvasElement });

引擎調整畫布大小的方式可以通過 canvasResizePolicy 覆蓋選項進行配置。

如果你的遊戲需要一些時間來載入,顯示一個追蹤進度的自訂載入UI可能是有用的。這可以通過 onProgress 回呼函式選項來實作,它允許設定一個回呼函式,當引擎載入新位元組時,該函式將被定期呼叫。

function printProgress(current, total) {
    console.log("Loaded " + current + " of " + total + " bytes");
}
engine.startGame({ onProgress: printProgress });

請注意,在某些情況下 total 可能是 0。這意味著無法計算。

如果你的遊戲支援多種語言, locale 覆蓋選項可以用來強制使用一個特定的語言,只要你有一個有效的語言程式碼字串。使用伺服器端的邏輯來確定使用者可能喜歡哪種語言可能較好。這樣,語言程式碼可以從 Accept-Language HTTP頭中獲取,或者由GeoIP服務決定。

除錯

要除錯匯出的專案, 可能需要讀取引擎生成的標準輸出和錯誤流. 這與編輯器控制台視窗中顯示的輸出類似. 預設情況下, 標準的 console.logconsole.warning 分別用於輸出和錯誤流. 這種行為可以通過設定自己的函式來處理消息來定制.

使用 onPrint 覆蓋選項為輸出流設定一個回呼函式,以及 onPrintError 覆蓋選項為錯誤流設定一個回呼函式。

function print(text) {
    console.log(text);
}
function printError(text) {
    console.warn(text);
}
engine.startGame({ onPrint: print, onPrintError: printError });

在處理引擎輸出時,請記住,在成品中列印出來可能是不可取的。