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.

Página HTML personalizada para la exportación web

Si bien las plantillas de exportación web proporcionan una página HTML predeterminada totalmente capaz de lanzar el proyecto sin ninguna personalización adicional, puede ser beneficioso crear una página HTML personalizada. Aunque el propio juego no puede ser controlado fácilmente desde el exterior, esta página permite personalizar el proceso de inicialización del motor.

Algunos casos de uso donde personalizar la página predeterminada es útil incluyen:

  • Cargar archivos de diferentes directorios;

  • Cargar archivos .zip en lugar de .pck como paquete principal;

  • Cargar archivos del motor desde un directorio distinto al paquete de datos principal;

  • Agregar un botón de "clic para jugar" para que los juegos puedan iniciarse en modo pantalla completa;

  • Cargar archivos extra antes de que arranque el motor, así estarán disponibles en el sistema de archivos luego;

  • Pasar argumentos personalizados por la línea de comandos, por ejemplo, -s para iniciar un script MainLoop.

La página HTML por defecto está disponible en el repositorio de Godot Engine en /misc/dist/html/full-size.html pero la siguiente plantilla puede ser usada como un ejemplo mucho mas sencillo:

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

Organización

Como se muestra en el ejemplo anterior, en su mayoría es un documento HTML regular, con algunos marcadores de posición que deben reemplazarse durante la exportación, un elemento HTML <canvas>, y un código JavaScript simple que llama a la clase Engine().

Los únicos marcadores de posición necesarios son:

  • $GODOT_URL: El nombre del archivo principal de JavaScript, que proporciona la clase Engine() necesaria para iniciar el motor y que debe incluirse en el HTML como un elemento <script>. El nombre se genera a partir de la Ruta de exportación durante el proceso de exportación.

  • $GODOT_CONFIG: Un objeto JavaScript que contiene las opciones de exportación y que puede ser anulado más adelante. Consulta EngineConfig para ver la lista completa de anulaciones.

Los siguientes marcadores de posición opcionales permitirán habilitar algunas características adicionales en tu plantilla HTML personalizada.

  • $GODOT_PROJECT_NAME: El nombre del proyecto tal como se define en la Configuración del proyecto. Es una buena idea utilizarlo como título (<title>) en tu plantilla.

  • $GODOT_HEAD_INCLUDE: Una cadena personalizada para incluir en el documento HTML justo antes del final de la etiqueta <head>. Se personaliza en las opciones de exportación en la sección Html / Head Include. Aunque tienes control total sobre la página HTML que creas, esta variable puede ser útil para configurar partes del elemento head del HTML desde el Editor de Godot, por ejemplo, para diferentes presets de exportación web.

Cuando la página personalizada esté lista, puedes seleccionarla en las opciones de exportación en la sección Html / Custom Html Shell (HTML personalizado).

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

Iniciando el proyecto

To be able to start the game, you need to write a script that initializes the engine — the control code. This process consists of three steps, but as shown here, most of them can be skipped depending on how much customization is needed.

Consulta la referencia de la clase HTML5 shell para ver la lista completa de métodos y opciones disponibles.

Primero, el motor debe ser cargado, luego necesita ser inicializado, y después de eso, finalmente se puede iniciar el proyecto. Puedes realizar cada uno de estos pasos manualmente y con un gran control. Sin embargo, en el caso más simple, todo lo que necesitas hacer es crear una instancia de la clase Engine() con la configuración exportada, y luego llamar al método engine.startGame anulando opcionalmente cualquier parámetro de EngineConfig.

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

This snippet of code automatically loads and initializes the engine before starting the game. It uses the given configuration to load the engine. The engine.startGame method is asynchronous and returns a Promise. This allows your control code to track if the game was loaded correctly without blocking execution or relying on polling.

En caso de que tu proyecto necesite tener un control especial sobre los argumentos de inicio y los archivos de dependencia, puedes utilizar el método engine.start. Ten en cuenta que este método no carga automáticamente el archivo pck, por lo que probablemente querrás cargarlo manualmente (y cualquier otro archivo adicional) a través del método engine.preloadFile.

Opcionalmente, también puedes utilizar engine.init para realizar acciones específicas después de la inicialización del módulo, pero antes de que el motor se inicie.

Este proceso es un poco más complejo, pero te brinda un control completo sobre el proceso de inicio del motor.

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

Para cargar el motor manualmente, debes llamar al método estático Engine.load(). Como este método es estático, puedes crear múltiples instancias del motor si comparten el mismo archivo wasm.

Nota

Por defecto, no se pueden crear múltiples instancias, ya que el motor se descarga inmediatamente después de inicializarse. Para evitar que esto ocurra, consulta la opción de anulación unloadAfterInit. Aún es posible descargar manualmente el motor posteriormente llamando al método estático Engine.unload(). La descarga del motor libera la memoria del navegador al descargar los archivos que ya no son necesarios una vez que se ha inicializado la instancia.

Personalizando el comportamiento

En el entorno web, se pueden utilizar varios métodos para garantizar que el juego funcione según lo previsto.

Si deseas orientar una versión específica de WebGL o simplemente quieres comprobar si WebGL está disponible en general, puedes llamar al método Engine.isWebGLAvailable(). Opcionalmente, puedes pasar un argumento que permite probar una versión mayor específica de WebGL.

En el entorno web, como el archivo ejecutable real no existe, el motor solo almacena un nombre de archivo virtual formado a partir del nombre base de los archivos del motor cargados. Este valor afecta la salida del método OS.get_executable_path() y define el nombre del paquete principal que se inicia automáticamente. La opción de anulación executable se puede utilizar para cambiar este valor y proporcionar un nombre personalizado para el archivo ejecutable en el entorno web.

Personalizando la presentación

Se pueden utilizar varias opciones de configuración para personalizar aún más el aspecto y el comportamiento del juego en tu página.

Por defecto, se utiliza el primer elemento canvas en la página para el renderizado. Para utilizar un elemento canvas diferente, puedes usar la opción de anulación canvas. Esta opción requiere una referencia al propio elemento DOM del canvas que deseas utilizar.

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

La forma en que el motor redimensiona el canvas se puede configurar a través de la opción de anulación canvasResizePolicy.

Si tu juego tarda un tiempo en cargarse, puede ser útil mostrar una interfaz de usuario de carga personalizada que rastree el progreso. Esto se puede lograr con la opción de devolución de llamada onProgress, que te permite configurar una función de devolución de llamada que se llamará regularmente a medida que el motor carga nuevos bytes.

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

Ten en cuenta que, en algunos casos, total puede ser 0. Esto significa que no se puede calcular.

Ten en cuenta que en algunos casos, total puede ser 0. Esto significa que no se puede calcular.

Depuración

Para depurar proyectos exportados, puede ser útil leer las secuencias de salida estándar y de error generadas por el motor. Esto es similar a la salida que se muestra en la ventana de la consola del editor. Por defecto, se utilizan los métodos estándar de console.log y console.warn para las secuencias de salida y error, respectivamente. Este comportamiento se puede personalizar configurando tus propias funciones para manejar los mensajes.

Utiliza la opción de anulación onPrint para establecer una función de devolución de llamada para la secuencia de salida (output stream) y la opción de anulación onPrintError para establecer una función de devolución de llamada para la secuencia de error.

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

When handling the engine output, keep in mind that it may not be desirable to print it out in the finished product.