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.

Eigene HTML Seiten für Web Export

Während Webexportvorlagen eine Standard-HTML-Seite bereitstellen, mit der das Projekt ohne weitere Anpassungen gestartet werden kann, kann es von Vorteil sein, eine eigene HTML-Seite zu erstellen. Während das Spiel selbst noch nicht direkt von außen gesteuert werden kann, ermöglicht eine solche Seite die Anpassung des Initialisierungsprozesses für die Engine.

Es gibt einige Anwendungsfälle, in denen die Anpassung der Standardseite nützlich ist:

  • Laden von Dateien aus einem anderen Verzeichnis als die Seite;

  • Laden einer .zip-Datei anstelle einer .pck Datei als Hauptpaket;

  • Laden der Engine aus einem anderen Verzeichnis als der Hauptpaketdatei;

  • Hinzufügen eines Click-to-Play-Buttons, damit Spiele im Vollbildmodus gestartet werden können;

  • Laden einiger zusätzlicher Dateien vor dem Start der Engine, um sie so schnell wie möglich im Projektdateisystem verfügbar zu machen;

  • Übergabe von benutzerdefinierten Kommandozeilenargumenten, z.B. -s, um ein MainLoop Skript zu starten.

Die Default-HTML-Seite ist im Godot-Engine-Repository unter /misc/dist/html/full-size.html verfügbar, aber die folgende Vorlage kann als viel einfacheres Beispiel verwendet werden:

<!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>

Einrichtung

Wie das obige Beispiel zeigt, handelt es sich größtenteils um ein normales HTML-Dokument mit einigen Platzhaltern, die beim Export ersetzt werden müssen, einem HTML-Element <canvas> und einigem einfachen JavaScript-Code, der die Klasse Engine() aufruft.

Die einzigen erforderlichen Platzhalter sind:

  • $GODOT_URL: Der Name der Haupt-JavaScript-Datei, von der die Engine()-Klasse bereitgestellt wird, die zum Starten der Engine erforderlich ist, und die als <script> in das HTML eingebunden werden muss. Der Name wird während des Exportvorgangs aus dem Exportpfad generiert.

  • $GODOT_CONFIG: Ein JavaScript-Objekt, das die Exportoptionen enthält und später überschrieben werden kann. Siehe EngineConfig für die vollständige Liste der Überschreibungen.

Die folgenden optionalen Platzhalter ermöglichen einige zusätzliche Funktionen in Ihrer benutzerdefinierten HTML-Vorlage.

  • $GODOT_PROJECT_NAME: Der Projektname, wie er in den Projekteinstellungen definiert ist. Es ist eine gute Idee, ihn als <title> in Ihrer Vorlage zu verwenden.

  • $GODOT_HEAD_INCLUDE: Ein benutzerdefinierter String, der in das HTML-Dokument kurz vor dem Ende des <head>-Tags eingefügt wird. Er wird in den Exportoptionen unter dem Abschnitt Html / Head Include angepasst. Während Sie die volle Kontrolle über die von Ihnen erstellte HTML-Seite haben, kann diese Variable nützlich sein, um Teile des HTML-Elements head aus dem Godot-Editor zu konfigurieren, z. B. für verschiedene Web-Export-Voreinstellungen.

Wenn die benutzerdefinierte Seite fertig ist, kann sie in den Exportoptionen unter dem Abschnitt Html / Custom Html Shell ausgewählt werden.

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

Starten des Projekts

Um das Spiel starten zu können, müssen Sie ein Skript schreiben, das die Engine initialisiert - den Steuercode. Dieser Prozess besteht aus drei Schritten, aber wie hier gezeigt, können die meisten davon übersprungen werden, je nachdem, wie viele Anpassungen erforderlich sind.

Siehe die HTML5-Shell-Klassenreferenz, für die vollständige Liste der verfügbaren Methoden und Optionen.

Zuerst muss die Engine geladen werden, dann muss sie initialisiert werden, und danach kann das Projekt schließlich gestartet werden. Sie können jeden dieser Schritte manuell und mit großer Kontrolle durchführen. Im einfachsten Fall genügt es jedoch, eine Instanz der Klasse Engine() mit der exportierten Konfiguration zu erstellen und dann die Methode engine.startGame aufzurufen, wobei alle EngineConfig-Parameter optional überschrieben werden.

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

Dieser Codeschnipsel lädt und initialisiert die Engine automatisch, bevor das Spiel gestartet wird. Er verwendet die angegebene Konfiguration, um die Engine zu laden. Die engine.startGame Methode ist asynchron und gibt ein Promise zurück. Dies erlaubt es Ihrem Kontrollcode zu verfolgen, ob das Spiel korrekt geladen wurde, ohne die Ausführung zu blockieren oder sich auf Polling zu verlassen.

Falls Ihr Projekt eine besondere Kontrolle über die Startargumente und Abhängigkeitsdateien benötigt, kann stattdessen die Methode engine.start verwendet werden. Beachten Sie, dass diese Methode die pck-Datei nicht automatisch vorlädt, so dass Sie sie (und jede andere zusätzliche Datei) wahrscheinlich manuell mit der Methode engine.preloadFile vorladen wollen.

Optional können Sie auch manuell engine.init verwenden, um bestimmte Aktionen nach der Initialisierung des Moduls, aber vor dem Start der Engine durchzuführen.

Dieses Verfahren ist etwas komplexer, gibt Ihnen aber die volle Kontrolle über den Startvorgang der Engine.

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!');
});

Um die Engine manuell zu laden, muss die statische Methode Engine.load() aufgerufen werden. Da diese Methode statisch ist, können mehrere Engine-Instanzen erzeugt werden, wenn sie denselben Wasm verwenden.

Bemerkung

Standardmäßig können nicht mehrere Instanzen erzeugt werden, da die Engine sofort nach ihrer Initialisierung entladen wird. Um dies zu verhindern, siehe die Überschreibungsoption unloadAfterInit. Es ist immer noch möglich, die Engine nachträglich manuell zu entladen, indem man die statische Methode Engine.unload() aufruft. Das Entladen der Engine gibt Browser-Speicher frei, indem es Dateien entlädt, die nicht mehr benötigt werden, sobald die Instanz initialisiert ist.

Das Verhalten anpassen

In der Web-Umgebung können mehrere Methoden eingesetzt werden, um zu gewährleisten, dass das Spiel wie vorgesehen funktioniert.

Wenn Sie auf eine bestimmte Version von WebGL abzielen oder einfach nur prüfen wollen, ob WebGL überhaupt verfügbar ist, können Sie die Methode Engine.isWebGLAvailable() aufrufen. Sie nimmt optional ein Argument entgegen, das es erlaubt, auf eine bestimmte Hauptversion von WebGL zu testen.

Da die echte ausführbare Datei in der Web-Umgebung nicht existiert, speichert die Engine nur einen virtuellen Dateinamen, der aus dem Basisnamen der geladenen Engine-Dateien gebildet wird. Dieser Wert beeinflusst die Ausgabe der Methode OS.get_executable_path() und definiert den Namen des automatisch gestarteten Hauptpakets. Die Option executable kann verwendet werden, um diesen Wert außer Kraft zu setzen.

Anpassen der Präsentation

Mehrere Konfigurationsoptionen können verwendet werden, um das Aussehen und Verhalten des Spiels auf Ihrer Seite weiter anzupassen.

Standardmäßig wird das erste Canvas-Element auf der Seite für das Rendering verwendet. Um ein anderes Canvas-Element zu verwenden, kann die Option canvas override verwendet werden. Sie erfordert einen Verweis auf das DOM-Element selbst.

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

Die Art und Weise, wie die Engine die Größe des Canvas ändert, kann über die Option canvasResizePolicy konfiguriert werden.

Wenn Ihr Spiel einige Zeit zum Laden benötigt, kann es nützlich sein, eine benutzerdefinierte Lade-UI anzuzeigen, die den Fortschritt verfolgt. Dies kann mit der Callback-Option onProgress erreicht werden, die es erlaubt, eine Callback-Funktion einzurichten, die regelmäßig aufgerufen wird, wenn die Engine neue Bytes lädt.

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

Beachten Sie, dass total in manchen Fällen 0 sein kann. Dies bedeutet, dass sie nicht berechnet werden kann.

Wenn Ihr Spiel mehrere Sprachen unterstützt, kann die Option locale verwendet werden, um ein bestimmtes Gebietsschema zu erzwingen, vorausgesetzt, Sie haben einen gültigen Sprachcode-String. Es kann sinnvoll sein, eine serverseitige Logik zu verwenden, um festzustellen, welche Sprachen ein Benutzer bevorzugt. Auf diese Weise kann der Sprachcode aus dem Accept-Language-HTTP-Header entnommen oder von einem GeoIP-Dienst ermittelt werden.

Debugging

Um exportierte Projekte zu debuggen, kann es nützlich sein, die von der Engine erzeugten Default-Ausgaben und Fehlerströme zu lesen. Dies ist vergleichbar mit der Ausgabe, die im Konsolenfenster des Editors angezeigt wird. Standardmäßig werden die Standard-console.log und -console.warn für die Ausgabe- bzw. Fehlerströme verwendet. Dieses Verhalten kann angepasst werden, indem man eigene Funktionen für die Behandlung von Meldungen einrichtet.

Verwenden Sie die Override-Option onPrint, um eine Callback-Funktion für den Ausgabestrom zu setzen, und die Override-Option onPrintError, um eine Callback-Funktion für den Fehlerstrom zu setzen.

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

Bedenken Sie bei der Handhabung der Engine-Ausgabe, dass es möglicherweise nicht wünschenswert ist, sie im fertigen Produkt auszugeben.