Plan A: frame loop al Director, interfaz Scene común
Cada escena ahora implementa una interfaz Scene { handleEvent, update,
draw, isFinished } y el Director es quien posee el bucle de frames.
Antes había tres bucles casi idénticos duplicados en logo/title/game
con ~30 LOC cada uno; ahora hay uno solo en Director::runFrameLoop.
Cambios:
- Nueva interfaz core/system/scene.hpp (pura virtual).
- Cada escena hereda final + override de handleEvent/update/draw/
isFinished. Los métodos privados que ya existían (update, draw,
processar_events) pasan a públicos como override; processar_events
se renombra a handleEvent.
- Director::run gestiona la transición entre escenas vía
buildScene(type) → runFrameLoop(scene), ambas estáticas.
- isFinished() = context_.nextScene() != mi_tipo, así que la única
vía de transición es context_.setNextScene().
- TitleScene tenía un bug latente: llamaba a setNextScene(GAME)
prematuramente al entrar en PLAYER_JOIN_PHASE, lo que con el nuevo
modelo habría saltado las animaciones de salida. Movido el
setNextScene al final de BLACK_SCREEN, que es donde la transición
ocurría de verdad (vía la variable global SceneManager::actual).
- LogoScene::draw llamaba a clear() y present() dentro del draw, una
anomalía. Sacados al Director para que la composición sea uniforme.
- Eliminadas todas las escrituras a SceneManager::actual desde las
escenas. El Director es ahora la única fuente que actualiza la
variable global (sigue ahí para lecturas externas, por compatibilidad).
Net: -60 LOC reales (las escenas pierden ~25 cada una de boilerplate),
y queda un único punto de inyección para los overlays globales que
vienen en el siguiente paso del roadmap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,12 +14,10 @@
|
||||
#include "core/audio/audio.hpp"
|
||||
#include "core/entities/entity.hpp"
|
||||
#include "core/input/input.hpp"
|
||||
#include "core/input/mouse.hpp"
|
||||
#include "core/math/easing.hpp"
|
||||
#include "core/physics/collision.hpp"
|
||||
#include "core/rendering/line_renderer.hpp"
|
||||
#include "core/system/scene_context.hpp"
|
||||
#include "core/system/global_events.hpp"
|
||||
#include "game/stage_system/stage_loader.hpp"
|
||||
#include "game/systems/collision_system.hpp"
|
||||
#include "game/systems/continue_system.hpp"
|
||||
@@ -64,69 +62,21 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context)
|
||||
for (auto& enemy : enemies_) {
|
||||
enemy = Enemy(sdl.getRenderer());
|
||||
}
|
||||
|
||||
// El resto del estado del juego (física, stages, naves, vidas, puntuación)
|
||||
// se inicializa en init(), que se llama al final del constructor para que
|
||||
// la escena esté lista en cuanto el Director la haya construido.
|
||||
init();
|
||||
}
|
||||
|
||||
void GameScene::run() {
|
||||
std::cout << "SceneType Juego: Inicialitzant...\n";
|
||||
auto GameScene::isFinished() const -> bool {
|
||||
return context_.nextScene() != SceneType::GAME;
|
||||
}
|
||||
|
||||
// Inicialitzar state del juego
|
||||
init();
|
||||
|
||||
SDL_Event event;
|
||||
Uint64 last_time = SDL_GetTicks();
|
||||
|
||||
while (SceneManager::actual == SceneType::GAME) {
|
||||
// Calcular delta_time real
|
||||
Uint64 current_time = SDL_GetTicks();
|
||||
float delta_time = (current_time - last_time) / 1000.0F;
|
||||
last_time = current_time;
|
||||
|
||||
// Limitar delta_time per evitar grandes salts
|
||||
delta_time = std::min(delta_time, 0.05F);
|
||||
|
||||
// Actualitzar counter de FPS
|
||||
sdl_.updateFPS(delta_time);
|
||||
|
||||
// Actualitzar visibilitat del cursor (auto-ocultar)
|
||||
Mouse::updateCursorVisibility();
|
||||
|
||||
// Actualitzar sistema de input ABANS del event loop
|
||||
Input::get()->update();
|
||||
|
||||
// Processar events SDL
|
||||
while (SDL_PollEvent(&event)) {
|
||||
// Manejo de finestra
|
||||
if (sdl_.handleWindowEvent(event)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Events globals (F1/F2/F3/ESC/QUIT)
|
||||
GlobalEvents::handle(event, sdl_, context_);
|
||||
}
|
||||
|
||||
// Actualitzar física del juego con delta_time real
|
||||
update(delta_time);
|
||||
|
||||
// Actualitzar sistema de audio
|
||||
Audio::update();
|
||||
|
||||
// Actualitzar colors oscil·lats
|
||||
sdl_.updateColors(delta_time);
|
||||
|
||||
// Netejar pantalla (usa color oscil·lat)
|
||||
sdl_.clear(0, 0, 0);
|
||||
|
||||
// Actualitzar context de renderizado (factor de scale global)
|
||||
sdl_.updateRenderingContext();
|
||||
|
||||
// Dibuixar juego
|
||||
draw();
|
||||
|
||||
// Presentar renderer (swap buffers)
|
||||
sdl_.present();
|
||||
}
|
||||
|
||||
std::cout << "SceneType Juego: Finalitzant...\n";
|
||||
void GameScene::handleEvent(const SDL_Event& event) {
|
||||
// GameScene no procesa eventos puntuales SDL: la lógica de input se
|
||||
// resuelve en update() consultando Input::checkAction.
|
||||
(void)event;
|
||||
}
|
||||
|
||||
void GameScene::init() {
|
||||
@@ -346,7 +296,6 @@ auto GameScene::stepGameOver(float delta_time) -> bool {
|
||||
if (game_over_timer_ <= 0.0F) {
|
||||
Audio::get()->stopMusic();
|
||||
context_.setNextScene(SceneType::TITLE);
|
||||
SceneManager::actual = SceneType::TITLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user