导出自定义HTML页面

虽然Web导出模板提供了一个默认的HTML页面,完全能够启动项目而不需要任何进一步的定制,但创建一个自定义的HTML页面可能是有益的。虽然游戏本身不能从外部直接控制,但这种页面允许自定义引擎的初始化过程。

自定义默认页面有用的一些用例包括:

  • 从其他目录加载文件;

  • 加载 .zip 文件而不是 .pck 文件作为主资源包;

  • 从主资源包文件以外的目录中加载引擎文件;

  • 添加一个“即点即玩”按钮,使游戏可以在全屏模式下启动;

  • 在引擎启动之前加载一些额外的文件,以便稍后在文件系统中可用;

  • 传递自定义“命令行”参数,例如 -s 启动``MainLoop``脚本。

默认的HTML页面可在Godot引擎存储库中找到,位于`/misc/dist/html/full-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/full- size.html>`__,可以用作参考实现。 另一个示例HTML页面位于`/misc/dist/html/fixed-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/fixed-size.html>`。 __。 与默认设置不同的是,它具有一个固定大小的画布区域,并且在其下方有一个输出小部件。

注解

建议使用浏览器供应商提供的开发者工具来调试导出的项目。引擎生成的输出可能是有限的,并且不包括WebGL错误。

场景布置

从默认的HTML页面可以看出,它主要是一个普通的HTML文档。要与Godot项目配合使用,需要完全实现,要有一个调用 Engine() 类的控制代码,并提供几个占位符的位置,在导出时用实际值替换。

../../_images/html5_export_options.png
  • $GODOT_BASENAME*导出路径*中的基本名称,在导出选项中设置;后缀被省略(例如,game.html``变成``game)。这个变量可以用来生成主JavaScript文件``$GODOT_BASENAME.js``的路径,它提供了:js:class:Engine`类。开机过程中显示的flash图片也可以使用这个变量来访问。``$GODOT_BASENAME.png`

  • $GODOT_PROJECT_NAME:项目设置中定义的项目名称。

  • $GODOT_HEAD_INCLUDE。在HTML文件中,在``<head>``标签结尾前包含的一个自定义字符串。它是在*Html / Head Include*部分的导出选项中自定义的。虽然你可以完全控制你所创建的HTML页面,但这个变量对于从Godot Editor中配置HTML``head``元素的部分内容很有用,例如,对于不同的Web导出预设。

  • $GODOT_DEBUG_ENABLED : 这是一个标志,用于说明这是否是一个调试构建。这个变量被字符串 truefalse 代替,可以用来禁用控制代码中的调试分支。

当自定义页面准备好后,可以在 Html / Custom Html Shell 部分的导出选项中选择。

Starting the project

为了能够启动游戏,你需要写一个初始化引擎的脚本--控制代码。这个过程包括三个步骤,尽管其中一些步骤可以跳过,并留下一个默认的行为。

首先,引擎必须被加载,然后需要初始化,在这之后,项目才能最终启动。你可以手动执行这些步骤,而且能控制许多东西。然而,在最简单的情况下,你需要做的就是创建一个 Engine() 类的实例,然后调用 engine.startGame() 方法。

const execName = "path://to/executable"
const mainPack = "path://to/main_pack"

const engine = new Engine();
engine.startGame(execName, mainPack)

这段代码在启动游戏前自动加载并初始化引擎。它使用给定的可执行文件路径来推断加载引擎的路径。 engine.startGame() 方法是异步的,并返回一个 Promise 。这允许你的控制代码跟踪游戏是否被正确加载,而无需阻止执行或依赖轮询。

如果你的项目需要由启动脚本传递给它特殊的参数, engine.startGame() 可以被 engine.start() 替换。这个方法接受一个任意的字符串参数列表。由于它没有定义参数列表,所以 engine.start() 不能自动加载引擎。

要手动加载引擎,必须调用 Engine.load() 静态方法。因为这个方法是静态的,所以可以用完全相同的 basePath 生成多个引擎实例。如果一个实例需要一个不同的 basePath ,你可以在启动游戏之前使用该路径调用 engine.init() 方法。

注解

默认情况下不能生成多个实例,因为引擎在初始化后会立即卸载。为了防止这种情况发生,可以调用 engine.setUnloadAfterInit() 方法。之后仍然可以通过调用 Engine.unload() 静态方法手动卸载引擎。卸载引擎通过卸载实例初始化后不再需要的文件来释放浏览器内存。

为了在某些主机提供商和网络配置上正确加载引擎,你可能需要通过使用 Engine.setWebAssemblyFilenameExtension() 来更改默认的文件名扩展。默认情况下,扩展名被假定为 wasm 。如果你的主机提供商屏蔽了这个扩展名,可以使用这个静态方法将其改为支持的扩展名。

Engine.setWebAssemblyFilenameExtension("dat");
// Load mygame.dat as WebAssembly module.
Engine.load("mygame");

警告

如果使用了不同的文件扩展名,一些网络服务器可能会自动将文件的MIME类型设置为 application/wasm 以外的其他类型。在这种情况下,一些启动优化可能会被跳过。

Customizing the behavior

在Web环境下,可以使用几种方法来保证游戏能够按照预期的方式运行。

如果您的目标是WebGL的特定版本,或者只是想检查WebGL是否可用,您可以调用 Engine.isWebGLAvailable() 方法。它可以选择接受一个参数,允许测试WebGL的特定主要版本。

由于真正的可执行文件在Web环境中并不存在,引擎只存储一个由加载的引擎文件的基名形成的虚拟文件名。这个值会影响 OS.get_executable_path() 方法的输出,并定义自动启动的主包名称。 engine.setExecutableName() 方法可以用来覆盖这个值。

如果你的项目需要一些文件在加载时就可以使用,你可以通过调用 engine.preloadFile() 方法来预加载它们,并提供一个文件的路径,或者提供一个 ArrayBuffer 对象。如果是 ArrayBuffer 或它的一个视图,必须指定第二个参数来定义加载资源的内部路径。

自定义演示文稿

有几种方法可以用来进一步定制您页面上的游戏外观和行为。

默认情况下,页面上的第一个画布元素被用于渲染。要使用不同的canvas元素,可以使用 engine.setCanvas() 方法。它需要一个DOM元素本身的引用。

const canvasElement = document.querySelector("#my-canvas-element");
engine.setCanvas(canvasElement);

如果这个canvas元素的宽度和高度与项目设置中设置的值不同,它将在项目启动时被调整大小。这个行为可以通过调用 engine.setCanvasResizedOnStart() 方法来禁止。

如果你的游戏需要一些时间来加载,那么显示一个自定义的加载UI来跟踪进度可能会很有用。这可以通过 engine.setProgressFunc() 方法来实现,该方法允许设置一个回调函数,在引擎加载新字节时定期调用。

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

请注意,在某些情况下, total 可能是 0 。这意味着无法计算。

如果你的游戏支持多种语言,只要你有一个有效的语言代码字符串,就可以使用 engine.setLocale() 方法来设置一个特定的语言环境。使用服务器端的逻辑来确定用户可能更喜欢哪种语言可能是个好办法。这样一来,语言代码可以从 Accept-Language HTTP头中获取,或者由GeoIP服务确定。

调试

要调试导出的项目,可能需要读取引擎生成的标准输出和错误流。这与编辑器控制台窗口中显示的输出类似。默认情况下,标准的 console.logconsole.warning 分别用于输出和错误流。这种行为可以通过设置自己的函数来处理消息来定制。

使用 engine.setStdoutFunc() 方法为输出流设置回调函数。默认行为与此类似:

function printStdout(text) {
    console.log(text);
}
engine.setStdoutFunc(printStdout);

使用 engine.setStderrFunc() 方法为错误流设置回调函数。默认行为与此类似:

function printStderr(text) {
    console.warn("Error: " + text);
}
engine.setStderrFunc(printStderr);

当处理引擎输出时,请记住,在生产环境中打印出来可能并不可取,如果要控制当前执行是否真的是调试构建,可以使用 $GODOT_DEBUG_ENABLED 占位符。

进一步的调试选项和对执行环境的低阶访问,可以通过Emscripten的 Module 对象的形式获得。它可以通过引擎实例上的 engine.rtenv 属性来访问。