fix: Preservar SimulationMode y mejorar Debug HUD

CAMBIOS:
- Debug HUD reorganizado en layout de 2 columnas (LEFT/RIGHT, sin centro)
- Añadidos getters públicos en Engine para info de sistema
- changeScenario() ahora preserva el SimulationMode actual
- Inicialización de pelotas según modo (PHYSICS/SHAPE/BOIDS)
- Eliminada duplicación de logo_entered_manually_ (ahora en StateManager)

ARCHIVOS MODIFICADOS:
- engine.h: Añadidos 8 getters públicos para UIManager
- engine.cpp: changeScenario() pasa current_mode_ a SceneManager
- scene_manager.h: changeScenario() acepta parámetro SimulationMode
- scene_manager.cpp: Inicialización según modo (RULES.md líneas 23-26)
- ui_manager.h: render() acepta Engine* y renderDebugHUD() actualizado
- ui_manager.cpp: Debug HUD con columnas LEFT (sistema) y RIGHT (física)

REGLAS.md IMPLEMENTADO:
 Líneas 23-26: Inicialización diferenciada por modo
  - PHYSICS: Top, 75% distribución central en X, velocidades aleatorias
  - SHAPE: Centro de pantalla, sin velocidad inicial
  - BOIDS: Posiciones y velocidades aleatorias
 Líneas 88-96: Debug HUD con información de sistema completa

BUGS CORREGIDOS:
- Fix: Cambiar escenario (1-8) en FIGURE ya no resetea a PHYSICS 
- Fix: Las pelotas se inicializan correctamente según el modo activo
- Fix: AppMode movido de centro a izquierda en Debug HUD

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-16 09:52:33 +02:00
parent 3d26bfc6fa
commit 8c2a8857fc
6 changed files with 239 additions and 101 deletions

View File

@@ -340,10 +340,14 @@ void Engine::update() {
// Gravedad y física
void Engine::handleGravityToggle() {
// Si estamos en modo boids, salir a modo física primero
// Si estamos en modo boids, salir a modo física CON GRAVEDAD OFF
// Según RULES.md: "BOIDS a PHYSICS: Pulsando la tecla G: Gravedad OFF"
if (current_mode_ == SimulationMode::BOIDS) {
toggleBoidsMode(); // Esto cambia a PHYSICS y activa gravedad
return; // La notificación ya se muestra en toggleBoidsMode
toggleBoidsMode(); // Cambiar a PHYSICS (preserva inercia, gravedad ya está OFF desde activateBoids)
// NO llamar a forceBallsGravityOff() porque aplica impulsos que destruyen la inercia de BOIDS
// La gravedad ya está desactivada por BoidManager::activateBoids() y se mantiene al salir
showNotificationForAction("Modo Física - Gravedad Off");
return;
}
// Si estamos en modo figura, salir a modo física SIN GRAVEDAD
@@ -504,13 +508,14 @@ void Engine::switchTexture() {
// Escenarios (número de pelotas)
void Engine::changeScenario(int scenario_id, const char* notification_text) {
// Resetear modo SHAPE si está activo
// Pasar el modo actual al SceneManager para inicialización correcta
scene_manager_->changeScenario(scenario_id, current_mode_);
// Si estamos en modo SHAPE, regenerar la figura con nuevo número de pelotas
if (current_mode_ == SimulationMode::SHAPE) {
current_mode_ = SimulationMode::PHYSICS;
active_shape_.reset();
generateShape();
}
scene_manager_->changeScenario(scenario_id);
showNotificationForAction(notification_text);
}
@@ -695,7 +700,7 @@ void Engine::render() {
*/
// Renderizar UI (debug HUD, texto obsoleto, notificaciones) - delegado a UIManager
ui_manager_->render(renderer_, scene_manager_.get(), current_mode_, state_manager_->getCurrentMode(),
ui_manager_->render(renderer_, this, scene_manager_.get(), current_mode_, state_manager_->getCurrentMode(),
active_shape_.get(), shape_convergence_,
physical_window_width_, physical_window_height_, current_screen_width_);
@@ -769,7 +774,7 @@ void Engine::toggleRealFullscreen() {
// Reinicar la escena con nueva resolución
scene_manager_->updateScreenSize(current_screen_width_, current_screen_height_);
scene_manager_->changeScenario(scene_manager_->getCurrentScenario());
scene_manager_->changeScenario(scene_manager_->getCurrentScenario(), current_mode_);
// Actualizar tamaño de pantalla para boids (wrapping boundaries)
boid_manager_->updateScreenSize(current_screen_width_, current_screen_height_);
@@ -794,7 +799,7 @@ void Engine::toggleRealFullscreen() {
// Reinicar la escena con resolución original
scene_manager_->updateScreenSize(current_screen_width_, current_screen_height_);
scene_manager_->changeScenario(scene_manager_->getCurrentScenario());
scene_manager_->changeScenario(scene_manager_->getCurrentScenario(), current_mode_);
}
}
@@ -1154,7 +1159,7 @@ void Engine::performLogoAction(bool logo_waiting_for_flip) {
// Solo salir automáticamente si la entrada a LOGO fue automática (desde DEMO)
// No salir si el usuario entró manualmente con tecla K
// Probabilidad de salir: 60% en cada acción → sale rápido (relación DEMO:LOGO = 6:1)
if (!logo_entered_manually_ && rand() % 100 < 60) {
if (!state_manager_->getLogoEnteredManually() && rand() % 100 < 60) {
state_manager_->exitLogoMode(true); // Volver a DEMO/DEMO_LITE
}
}
@@ -1313,7 +1318,7 @@ void Engine::executeDemoAction(bool is_lite) {
// Escenarios válidos: índices 1, 2, 3, 4, 5 (10, 100, 500, 1000, 10000 pelotas)
int valid_scenarios[] = {1, 2, 3, 4, 5};
int new_scenario = valid_scenarios[rand() % 5];
scene_manager_->changeScenario(new_scenario);
scene_manager_->changeScenario(new_scenario, current_mode_);
return;
}
@@ -1398,7 +1403,7 @@ void Engine::executeRandomizeOnDemoStart(bool is_lite) {
// 1. Escenario (excluir índices 0, 6, 7)
int valid_scenarios[] = {1, 2, 3, 4, 5};
int new_scenario = valid_scenarios[rand() % 5];
scene_manager_->changeScenario(new_scenario);
scene_manager_->changeScenario(new_scenario, current_mode_);
// 2. Tema (elegir entre TODOS los 15 temas)
int random_theme_index = rand() % 15;
@@ -1463,7 +1468,7 @@ void Engine::executeEnterLogoMode(size_t ball_count) {
// Verificar mínimo de pelotas
if (static_cast<int>(ball_count) < LOGO_MODE_MIN_BALLS) {
// Ajustar a 5000 pelotas automáticamente
scene_manager_->changeScenario(5); // Escenario 5000 pelotas (índice 5 en BALL_COUNT_SCENARIOS)
scene_manager_->changeScenario(5, current_mode_); // Escenario 5000 pelotas (índice 5 en BALL_COUNT_SCENARIOS)
}
// Guardar estado previo (para restaurar al salir)