Control de escenas

Cómo gestionar escenas en Phaser


En el capítulo anterior vimos las bases del ciclo de vida de una escena de Phaser. Sin embargo, aún no hemos visto como controlar las escenas, saltar de una a otra, pausarlas, etc...

Iniciar una escena

Observa el siguiente fragmento de código. Nos encontramos en la función create() de la escena Start. En este caso, estamos iniciando la escena Menu directamente porque ya la habíamos precargado en el array de escenas del objeto de configuración, pero también podríamos hacerlo de forma explícita, sin tenerla precargada:

import Menu from "@scenes/Menu.js";

export class Start extends Phaser.Scene {
  create() {

    // Método A (Menu ya estaba precargado en array de escenas)
    this.scene.start("Menu");

    // Método B (Se precarga Menu en el array de escenas)
    this.scene.stop("Start");
    this.scene.add("Menu", Menu, true);

    const currentState = this.scene.getStatus("Menu");
  }
}

Observa que en ambos casos, la escena actual (Start) pasará a shutdown y la escena Menu pasará a running. Sólo que en el Método B estamos asumiendo que la escena no había sido incluida en el array de escenas de la configuración, por lo que tenemos hacerlo manualmente. A veces interesa, porque la escena la cargamos sólo en ciertos casos que sabemos que se ejecutará en un futuro.

Métodos de control de escenas

En el ejemplo anterior hemos utilizado los métodos de escena start(), stop() y add(), pero hay muchos más, que permiten realizar otras tareas, con variaciones y moviendo a un estado diferente las escenas. Echemos un vistazo:

Método Descripción
start(scene) Inicia una escena (y detiene la actual).
pause(scene) Pausa una escena (no update, pero si render).
resume(scene) Reanuda una escena pausada (reanuda update).
stop(scene) Detiene una escena.
restart() Reinicia una escena.
sleep(scene) Duerme una escena (no update, no render).
wake(scene) Despierta una escena (reanuda update y render).

A estos métodos tenemos que pasarle el nombre o key de la escena scene (o la propia clase). Además, podemos pasarle otro parámetro con los datos que queramos compartir con la escena, algo que veremos más adelante.

Todas las escenas tienen un estado interno que nos indica en la fase en la que se encuentra. Puedes obtenerlo con el método getStatus(scene), como ves en la última línea superior. Esos estados son los que puedes ver en este diagrama:

Estados de las escenas en Phaser

Métodos avanzados

Además de estos métodos que hemos visto, tenemos algunos otros métodos que realizan algunas acciones adicionales y también pueden resultarnos interesantes. Recuerda que las escenas no tienen porque ser sólo pantallas completas, sino que pueden ser pequeñas regiones como ventanas con ítems o zonas específicas y puedes estar interesado en iniciar varias escenas a la vez:

Método Descripción
launch(scene) Inicia una escena en paralelo con la actual (No detiene la actual).
run(scene) Idem a la anterior. Ejecuta aunque no esté iniciada, esté dormida o esté pausada.
switch(scene) Duerme la escena actual e inicia la indicada.

El método launch() y run() son muy similares, aunque run() es especialmente interesante en casos donde has abierto una escena modal pausando la escena actual y quieres reanudarla.

Control de la lista de escenas

Recuerda que en nuestro objeto de configuración inicial, teníamos un con la lista de escenas inicial de nuestro juego. Como hemos dicho que las escenas pueden ser partes de una misma pantalla, nos puede interesar ordenar la lista para que algunas escenas salgan encima de otras, por ejemplo.

Podemos manipular esa lista de escenas en cualquier momento, utilizando los siguientes métodos:

Método Descripción
add(key, SceneFile, autostart) Añade una escena a la lista de escenas global.
remove(scene) Elimina una escena de la lista de escenas.
bringToTop(scene) Coloca la escena indicada al principio de la lista.
sendToBack(scene) Coloca la escena indicada al final de la lista.
moveAbove(scene, sceneB) Coloca la escena indicada por encima de la escena B.
moveUp(scene) Mueve la escena indicada una posición antes.
moveDown(scene) Mueve la escena indicada una posición después.
moveBelow(scene, sceneB) Coloca la escena indicada por debajo de la escena B.
swapPosition(sceneA, sceneB) Intercambia la escena A por la escena B.

Antes vimos un ejemplo de this.scene.add(), pero también tenemos todas estas funciones que, como ves, son muy sencillas de entender y manipulan el con la lista de escenas del juego.

Métodos de información

Por último, ten en cuenta que tienes algunos métodos interesantes para obtener información de una escena, así como variar algunos detalles concretos de la misma:

Método Descripción
get(key) Obtiene una escena por su id.
getIndex(index) Obtiene una escena por su posición numérica.
getStatus(scene) Obtiene el estado de la escena.
isActive(scene) Comprueba si una escena está activa.
isPaused(scene) Comprueba si una escena está pausada.
isSleeping(scene) Comprueba si una escena está dormida.
isVisible(scene) Comprueba si una escena está visible.
setActive(value, scene) Activa/desactiva la escena indicada.
setVisible(value, scene) Muestra/oculta la escena indicada.

Veamos estos métodos en acción en algunos ejemplos donde obtenemos o modificación información:

export class Start extends Phaser.Scene {
  created() {

    const gameScene = this.scene.get("Game");
    const firstScene = this.scene.getIndex(0);
    const menuStatus = this.scene.getStatus("Menu");
    const isVisible = this.scene.isVisible("GameOver");
    this.scene.setActive(false, "GameOver");
  }
}

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev