Page HTML custom pour un export Web

Bien que les modèles d'exportation Web fournissent une page HTML par défaut entièrement capable de lancer le projet sans autre personnalisation, il peut être utile de créer une page HTML personnalisée. Bien que le jeu lui-même ne puisse pas encore être contrôlé directement de l'extérieur, une telle page permet de personnaliser le processus d'initialisation du moteur.

Quelques cas pratique où une telle page puisse être utile :

  • Chargement de fichiers à partir d'un répertoire différent de la page ;

  • Chargement d'un fichier .zip au lieu d'un fichier .pck comme paquet principal ;

  • Chargement du moteur à partir d'un répertoire différent de celui du fichier du pack principal ;

  • Ajout d'un bouton click-to-play pour que les jeux puissent être lancés en mode plein écran ;

  • Chargement de quelques fichiers supplémentaires avant le démarrage du moteur, en les rendant disponibles dans le système de fichiers du projet dès que possible ;

  • Passer des arguments de ligne de commande personnalisés, par exemple -s pour démarrer un script MainLoop.

La page HTML par défaut est disponible dans le dépôt du moteur Godot à /misc/dist/html/full-size.html mais le modèle suivant peut être utilisé comme un exemple beaucoup plus simple :

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

Configuration

As shown by the example above, it is mostly a regular HTML document, with few placeholders which needs to be replaced during export, an html <canvas> element, and some simple JavaScript code that calls the Engine() class.

Les seuls caractères de remplacement requis sont :

  • $GODOT_URL: The name of the main JavaScript file, which provides the Engine() class required to start the engine and that must be included in the HTML as a <script>. The name is generated from the Export Path during the export process.

  • $GODOT_CONFIG: A JavaScript object, containing the export options and can be later overridden. See EngineConfig for the full list of overrides.

The following optional placeholders will enable some extra features in your cusstom HTML template.

  • $GODOT_PROJECT_NAME : Le nom du projet tel que défini dans les paramètres du projet. C'est une bonne idée de l'utiliser comme <title> dans votre modèle.

  • $GODOT_HEAD_INCLUDE : Une chaîne de charactère customisée à inclure dans le document HTML, juste avant la fin du tag <head>. Elle est spécifié dans les options d'export dans la section Html / Head Include . Même si vous avez le contrôle total de la page HTML que vous créez, cette variable peut être utile pour configurer une partie des éléments tagué head depuis l'éditeur Godot. Par exemple, pour différents préreglages d'export Web.

Quand la page custom est prête, elle peut être sélectionné dans les options d'exports dans la section Html / Custom Html Shell.

../../_images/html5_export_options.png

Démarrage du projet

Pour pouvoir démarrer le jeu, vous devez écrire un script qui initialise le moteur - le code de contrôle. Ce processus se compose de trois étapes, bien que, comme indiqué, la plupart d'entre elles peuvent être sautées en fonction du degré de personnalisation nécessaire (ou être laissées à un comportement par défaut).

See the HTML5 shell class reference, for the full list of methods and options available.

Tout d'abord, le moteur doit être chargé, puis il doit être initialisé, et après cela, le projet peut enfin être lancé. Vous pouvez effectuer chacune de ces étapes manuellement et avec un grand contrôle. Cependant, dans le cas le plus simple, il suffit de créer une instance de la classe Engine() avec la configuration exportée, puis d'appeler la méthode engine.startGame en surchargeant éventuellement les paramètres EngineConfig.

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

Ce bout de code charge et initialise automatiquement le moteur avant de lancer le jeu. Il utilise la configuration donnée pour charger le moteur. La méthode engine.startGame est asynchrone et renvoie un Promise. Cela permet à votre code de contrôle de savoir si le jeu a été chargé correctement sans bloquer l'exécution ou s'appuyer sur des sondages(polling).

In case your project needs to have special control over the start arguments and dependency files, the engine.start method can be used instead. Note, that this method do not automatically preload the pck file, so you will probably want to manually preload it (and any other extra file) via the engine.preloadFile method.

Optionally, you can also manually engine.init to perform specific actions after the module initialization, but before the engine starts.

This process is a bit more complex, but gives you full control over the engine startup process.

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

Pour charger le moteur manuellement, la méthode statique Engine.load() doit être appelée. Comme cette méthode est statique, plusieurs instances de moteur peuvent être créées si elles partagent le même wasm.

Note

Des instances multiples ne peuvent pas être créées par défaut, car le moteur est immédiatement déchargé après son initialisation. Pour empêcher cela, utilisez l'option unloadAfterInit. Il est toujours possible de décharger le moteur manuellement en appelant la méthode statique Engine.unload(). Le déchargement du moteur libère la mémoire du navigateur en déchargeant les fichiers qui ne sont plus nécessaires une fois l'instance initialisée.

Personnaliser le comportement

Dans l'environnement web, plusieurs méthodes peuvent être utilisés pour garantir que le jeu fonctionne comme prévu.

Si vous ciblez une version spécifique de WebGL ou que voulez juste vérifier que WebGL est disponible tout court, vous pouvez appeler la méthode Engine.isWebGLAvailable(). Elle prends optionnellement un argument qui permet de faire un test pour une version majeur spécifique de WebGL.

Alors que le véritable fichier exécutable n'existe pas dans l'environnement Web, le moteur de jeu stocke seulement un nom de fichier virtuel, formé du nom de base des fichiers chargé du moteur. Cette valeur affecte les données de sorties de la méthode OS.get_executable_path() et défini le nom du paquet principal automatiquement démarré. L'option de substitution executable peut être utilisée pour remplacer cette valeur.

Personnalisation de la présentation

Plusieurs options de configuration peuvent être utilisées pour personnaliser davantage l'aspect et le comportement du jeu sur votre page.

Par défaut, le premier élément du canvas sur la page est utilisé pour le rendu graphique. Pour utiliser un élément canvas différent, la méthode canvas peut être utilisée. Elle nécessite une référence à l'élément DOM lui-même.

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

The way the engine resize the canvas can be configured via the canvasResizePolicy override option.

Si le chargement de votre jeu prend un certain temps, il peut être utile d'afficher une interface de chargement personnalisée qui suit la progression. Cela peut être réalisé avec la méthode onProgress qui permet de mettre en place une fonction de rappel qui sera appelée régulièrement au fur et à mesure que le moteur charge de nouveaux octets.

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

Sachez que dans certains cas, total peut être 0. Cela signifie qu'il ne peut pas être calculé.

Si votre jeu prend en charge plusieurs langues, l'option de substitution locale peut être utilisée pour forcer un paramètre régional spécifique, à condition que vous disposiez d'un string de code de langue valide. Il peut être intéressant d'utiliser une logique côté serveur pour déterminer les langues préférées d'un utilisateur. Ainsi, le code de langue peut être extrait de l'en-tête HTTP Accept-Language, ou déterminé par un service GeoIP.

Débogage

Pour déboguer les projets exportés, il peut être utile de lire la sortie standard et les flux d'erreurs générés par le moteur. Ceci est similaire à la sortie affichée dans la fenêtre de la console de l'éditeur. Par défaut, les fichiers standard console.log et console.warn sont utilisés respectivement pour la sortie et le flux d'erreurs. Ce comportement peut être personnalisé en définissant vos propres fonctions pour traiter les messages.

Use the onPrint override option to set a callback function for the output stream, and the onPrintError override option to set a callback function for the error stream.

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

Lorsque vous manipulez la sortie du moteur, n'oubliez pas qu'il n'est peut-être pas souhaitable de l'imprimer dans le produit fini.