AWESOME ENGINE / GUÍA TÉCNICA

Escenas y ciclo de vida

El contrato Scene, el registro de juegos, las transiciones diferidas y la limpieza de estado.

En esta página

El contrato de una escena

Una escena recibe EngineContext por referencia y define cómo comenzar, actualizarse y dibujarse. Este contrato existe en la revisión de referencia:

class Scene {
protected:
  EngineContext &ctx;

public:
  Scene(EngineContext &context) : ctx(context) {}
  virtual ~Scene() = default;

  virtual void Start() = 0;
  virtual void Update() = 0;
  virtual void Render() const = 0;

  virtual void OnEvent(const sf::Event &) {};
  virtual void OnPause(bool /* pausa */) {};
  virtual void OnCleanup() {};
};

Start, Update y Render son obligatorios. Los demás callbacks tienen una implementación vacía y se especializan cuando el juego los necesita.

Responsabilidades por etapa

Etapa Cuándo ocurre Uso dentro del juego
Constructor Al crear el registro inicial de escenas. Preparar objetos y recursos de la instancia.
Start Al activar o reiniciar la escena. Restablecer la partida y registrar sus controles.
OnEvent Al recibir eventos con el overlay oculto. Atender eventos discretos del juego.
Update Por frame, con foco y sin overlay visible. Avanzar lógica, movimiento y estado.
Render Al dibujar el frame de la escena activa. Enviar objetos a ctx.renderer.
OnPause Cuando cambia el estado de pausa. Pausar o reanudar los elementos que controla la escena.
OnCleanup Antes de salir o reiniciar la escena. Detener audio y limpiar estado que no debe continuar.

El constructor y Start no son equivalentes. Las instancias permanecen en el registro y pueden recibir Start varias veces.

Registro de juegos

SceneFactory::Scenes es un unordered_map que asocia nombres con unique_ptr<Scene>. La fábrica registra siete instancias:

scenes.emplace("Bounce", std::make_unique<Bounce::Game>(context));
scenes.emplace("Clicker", std::make_unique<Clicker::Game>(context));
scenes.emplace("MemoryCard", std::make_unique<MemoryCard::Game>(context));
scenes.emplace("TicTacToe", std::make_unique<TicTacToe::Game>(context));
scenes.emplace("MineSweeper", std::make_unique<MineSweeper::Game>(context));
scenes.emplace("Runner", std::make_unique<Runner::Game>(context));
scenes.emplace("Tetris", std::make_unique<Tetris::Game>(context));

La revisión documentada solicita Tetris en el constructor de Engine. Los nombres son claves exactas del registro; una escena desconocida no tiene una ruta de recuperación implementada.

Transición diferida

SceneManager::ChangeScene almacena el nombre solicitado si todavía no hay otro cambio pendiente. Engine consume esa solicitud al principio del siguiente procesamiento de eventos.

ChangeScene(nombre)
     ↓
Solicitud pendiente
     ↓
Siguiente ProcessEvent
     ↓
OnCleanup de la escena anterior
     ↓
Limpieza de partículas y bindings de entrada
     ↓
Cambio del puntero activo
     ↓
Start de la escena solicitada
     ↓
Sincronización de pausa

RestartCurrentScene utiliza el mismo mecanismo con el nombre actual. No destruye y reconstruye el objeto: por eso Start debe dejar la partida en un estado válido al repetirse.

Explorar una implementación real

Bounce muestra cómo una clase de juego recibe el contexto, prepara su paleta y estadísticas, solicita sonido y música y utiliza los callbacks de escena.

Para incorporar una escena en tu propia copia, sigue la separación existente: declaración en Games/Include, implementación en Games/Source y registro explícito en SceneFactory.cpp. CMake descubre los .cpp de esas carpetas con GLOB_RECURSE CONFIGURE_DEPENDS; no existe un plugin de escenas cargado en tiempo de ejecución.

Limitación del acceso al menú

El overlay incluye un botón Menu, y el atajo M llama al mismo flujo. Engine solicita una escena llamada Menu, pero la fábrica de esta revisión no la registra. Evita esa acción al explorar esta versión: puede activar una aserción o una excepción por clave inexistente.

Esta documentación conserva esa limitación de forma explícita; no presenta el menú como un selector de juegos disponible.

Fuentes

Basado en código fuente verificado.¿Encontraste un problema? →