Refactor fase 8: Migrar lógica DEMO/LOGO a StateManager
Implementación: - StateManager::update() ahora maneja timers y triggers DEMO/LOGO - Detección de flips de PNG_SHAPE migrada completamente - Callbacks temporales en Engine para acciones complejas - enterLogoMode() y exitLogoMode() públicos para transiciones automáticas - Toggle methods en Engine delegados a StateManager Callbacks implementados (temporal para Fase 9): - Engine::performLogoAction() - Engine::executeDemoAction() - Engine::executeRandomizeOnDemoStart() - Engine::executeToggleGravityOnOff() - Engine::executeEnterLogoMode() - Engine::executeExitLogoMode() TODO Fase 9: - Eliminar callbacks moviendo lógica completa a StateManager - Limpiar duplicación de estado entre Engine y StateManager 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -321,8 +321,8 @@ void Engine::update() {
|
||||
updateShape();
|
||||
}
|
||||
|
||||
// Actualizar Modo DEMO (auto-play)
|
||||
updateDemoMode();
|
||||
// Actualizar Modo DEMO/LOGO (delegado a StateManager)
|
||||
state_manager_->update(delta_time_, shape_convergence_, active_shape_.get());
|
||||
|
||||
// Actualizar transiciones de temas (delegado a ThemeManager)
|
||||
theme_manager_->update(delta_time_);
|
||||
@@ -477,41 +477,42 @@ void Engine::handleZoomOut() {
|
||||
}
|
||||
}
|
||||
|
||||
// Modos de aplicación (DEMO/LOGO)
|
||||
// Modos de aplicación (DEMO/LOGO) - Delegados a StateManager
|
||||
void Engine::toggleDemoMode() {
|
||||
if (state_manager_->getCurrentMode() == AppMode::DEMO) {
|
||||
// Ya estamos en DEMO → volver a SANDBOX
|
||||
setState(AppMode::SANDBOX);
|
||||
AppMode prev_mode = state_manager_->getCurrentMode();
|
||||
state_manager_->toggleDemoMode(current_screen_width_, current_screen_height_);
|
||||
AppMode new_mode = state_manager_->getCurrentMode();
|
||||
|
||||
// Mostrar notificación según el modo resultante
|
||||
if (new_mode == AppMode::SANDBOX && prev_mode != AppMode::SANDBOX) {
|
||||
showNotificationForAction("MODO SANDBOX");
|
||||
} else {
|
||||
// Estamos en otro modo → ir a DEMO
|
||||
setState(AppMode::DEMO);
|
||||
randomizeOnDemoStart(false);
|
||||
} else if (new_mode == AppMode::DEMO && prev_mode != AppMode::DEMO) {
|
||||
showNotificationForAction("MODO DEMO");
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::toggleDemoLiteMode() {
|
||||
if (state_manager_->getCurrentMode() == AppMode::DEMO_LITE) {
|
||||
// Ya estamos en DEMO_LITE → volver a SANDBOX
|
||||
setState(AppMode::SANDBOX);
|
||||
AppMode prev_mode = state_manager_->getCurrentMode();
|
||||
state_manager_->toggleDemoLiteMode(current_screen_width_, current_screen_height_);
|
||||
AppMode new_mode = state_manager_->getCurrentMode();
|
||||
|
||||
// Mostrar notificación según el modo resultante
|
||||
if (new_mode == AppMode::SANDBOX && prev_mode != AppMode::SANDBOX) {
|
||||
showNotificationForAction("MODO SANDBOX");
|
||||
} else {
|
||||
// Estamos en otro modo → ir a DEMO_LITE
|
||||
setState(AppMode::DEMO_LITE);
|
||||
randomizeOnDemoStart(true);
|
||||
} else if (new_mode == AppMode::DEMO_LITE && prev_mode != AppMode::DEMO_LITE) {
|
||||
showNotificationForAction("MODO DEMO LITE");
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::toggleLogoMode() {
|
||||
if (state_manager_->getCurrentMode() == AppMode::LOGO) {
|
||||
// Ya estamos en LOGO → volver a SANDBOX
|
||||
exitLogoMode(false);
|
||||
AppMode prev_mode = state_manager_->getCurrentMode();
|
||||
state_manager_->toggleLogoMode(current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
|
||||
AppMode new_mode = state_manager_->getCurrentMode();
|
||||
|
||||
// Mostrar notificación según el modo resultante
|
||||
if (new_mode == AppMode::SANDBOX && prev_mode != AppMode::SANDBOX) {
|
||||
showNotificationForAction("MODO SANDBOX");
|
||||
} else {
|
||||
// Estamos en otro modo → ir a LOGO
|
||||
enterLogoMode(false);
|
||||
} else if (new_mode == AppMode::LOGO && prev_mode != AppMode::LOGO) {
|
||||
showNotificationForAction("MODO LOGO");
|
||||
}
|
||||
}
|
||||
@@ -949,44 +950,14 @@ void Engine::updatePhysicalWindowSize() {
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Sistema de gestión de estados (MANUAL/DEMO/DEMO_LITE/LOGO)
|
||||
// CALLBACKS PARA STATEMANAGER - FASE 8
|
||||
// ============================================================================
|
||||
// NOTA: Estos métodos son callbacks temporales para que StateManager pueda
|
||||
// ejecutar acciones que requieren acceso a múltiples componentes del Engine.
|
||||
// TODO FASE 9: Eliminar estos callbacks moviendo la lógica completa a StateManager
|
||||
|
||||
void Engine::setState(AppMode new_mode) {
|
||||
// Delegar a StateManager pero mantener lógica de setup en Engine temporalmente
|
||||
// TODO: Mover toda esta lógica a StateManager
|
||||
|
||||
// Aplicar el nuevo modo a través de StateManager
|
||||
state_manager_->setState(new_mode, current_screen_width_, current_screen_height_);
|
||||
|
||||
// Configurar timer de demo según el modo
|
||||
if (new_mode == AppMode::DEMO || new_mode == AppMode::DEMO_LITE || new_mode == AppMode::LOGO) {
|
||||
demo_timer_ = 0.0f;
|
||||
float min_interval, max_interval;
|
||||
|
||||
if (new_mode == AppMode::LOGO) {
|
||||
// Escalar tiempos con resolución (720p como base)
|
||||
float resolution_scale = current_screen_height_ / 720.0f;
|
||||
logo_min_time_ = LOGO_ACTION_INTERVAL_MIN * resolution_scale;
|
||||
logo_max_time_ = LOGO_ACTION_INTERVAL_MAX * resolution_scale;
|
||||
|
||||
min_interval = logo_min_time_;
|
||||
max_interval = logo_max_time_;
|
||||
} else {
|
||||
bool is_lite = (new_mode == AppMode::DEMO_LITE);
|
||||
min_interval = is_lite ? DEMO_LITE_ACTION_INTERVAL_MIN : DEMO_ACTION_INTERVAL_MIN;
|
||||
max_interval = is_lite ? DEMO_LITE_ACTION_INTERVAL_MAX : DEMO_ACTION_INTERVAL_MAX;
|
||||
}
|
||||
|
||||
demo_next_action_time_ = min_interval + (rand() % 1000) / 1000.0f * (max_interval - min_interval);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Sistema de Modo DEMO (auto-play)
|
||||
// ============================================================================
|
||||
|
||||
void Engine::updateDemoMode() {
|
||||
// Callback para ejecutar acciones de LOGO MODE
|
||||
void Engine::performLogoAction(bool logo_waiting_for_flip) {
|
||||
// Verificar si algún modo demo está activo (DEMO, DEMO_LITE o LOGO)
|
||||
if (state_manager_->getCurrentMode() == AppMode::SANDBOX) return;
|
||||
|
||||
@@ -1130,13 +1101,13 @@ void Engine::updateDemoMode() {
|
||||
// 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) {
|
||||
exitLogoMode(true); // Volver a DEMO/DEMO_LITE
|
||||
state_manager_->exitLogoMode(true); // Volver a DEMO/DEMO_LITE
|
||||
}
|
||||
}
|
||||
// MODO DEMO/DEMO_LITE: Acciones normales
|
||||
else {
|
||||
bool is_lite = (state_manager_->getCurrentMode() == AppMode::DEMO_LITE);
|
||||
performDemoAction(is_lite);
|
||||
executeDemoAction(is_lite);
|
||||
|
||||
// Resetear timer y calcular próximo intervalo aleatorio
|
||||
demo_timer_ = 0.0f;
|
||||
@@ -1150,7 +1121,8 @@ void Engine::updateDemoMode() {
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::performDemoAction(bool is_lite) {
|
||||
// Callback para StateManager - Ejecutar acción DEMO
|
||||
void Engine::executeDemoAction(bool is_lite) {
|
||||
// ============================================
|
||||
// SALTO AUTOMÁTICO A LOGO MODE (Easter Egg)
|
||||
// ============================================
|
||||
@@ -1161,7 +1133,7 @@ void Engine::performDemoAction(bool is_lite) {
|
||||
theme_manager_->getCurrentThemeIndex() == 5) { // MONOCHROME
|
||||
// 10% probabilidad de saltar a Logo Mode
|
||||
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE) {
|
||||
enterLogoMode(true); // Entrar desde DEMO
|
||||
state_manager_->enterLogoMode(true, current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1170,7 +1142,7 @@ void Engine::performDemoAction(bool is_lite) {
|
||||
if (static_cast<int>(scene_manager_->getBallCount()) >= LOGO_MODE_MIN_BALLS) {
|
||||
// 15% probabilidad de saltar a Logo Mode
|
||||
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO) {
|
||||
enterLogoMode(true); // Entrar desde DEMO
|
||||
state_manager_->enterLogoMode(true, current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1200,7 +1172,7 @@ void Engine::performDemoAction(bool is_lite) {
|
||||
// Toggle gravedad ON/OFF (20%)
|
||||
accumulated_weight += DEMO_LITE_WEIGHT_GRAVITY_TOGGLE;
|
||||
if (random_value < accumulated_weight) {
|
||||
toggleGravityOnOff();
|
||||
executeToggleGravityOnOff();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1243,7 +1215,7 @@ void Engine::performDemoAction(bool is_lite) {
|
||||
// Toggle gravedad ON/OFF (8%)
|
||||
accumulated_weight += DEMO_WEIGHT_GRAVITY_TOGGLE;
|
||||
if (random_value < accumulated_weight) {
|
||||
toggleGravityOnOff();
|
||||
executeToggleGravityOnOff();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1334,8 +1306,8 @@ void Engine::performDemoAction(bool is_lite) {
|
||||
}
|
||||
}
|
||||
|
||||
// Randomizar todo al iniciar modo DEMO
|
||||
void Engine::randomizeOnDemoStart(bool is_lite) {
|
||||
// Callback para StateManager - Randomizar estado al iniciar DEMO
|
||||
void Engine::executeRandomizeOnDemoStart(bool is_lite) {
|
||||
// Si venimos de LOGO con PNG_SHAPE, cambiar figura obligatoriamente
|
||||
// PNG_SHAPE es exclusivo del modo LOGO y no debe aparecer en DEMO/DEMO_LITE
|
||||
if (current_shape_type_ == ShapeType::PNG_SHAPE) {
|
||||
@@ -1363,7 +1335,7 @@ void Engine::randomizeOnDemoStart(bool is_lite) {
|
||||
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||
scene_manager_->changeGravityDirection(new_direction);
|
||||
if (rand() % 2 == 0) {
|
||||
toggleGravityOnOff(); // 50% probabilidad de desactivar gravedad
|
||||
executeToggleGravityOnOff(); // 50% probabilidad de desactivar gravedad
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1409,13 +1381,13 @@ void Engine::randomizeOnDemoStart(bool is_lite) {
|
||||
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||
scene_manager_->changeGravityDirection(new_direction);
|
||||
if (rand() % 3 == 0) { // 33% probabilidad de desactivar gravedad
|
||||
toggleGravityOnOff();
|
||||
executeToggleGravityOnOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle gravedad ON/OFF para todas las pelotas
|
||||
void Engine::toggleGravityOnOff() {
|
||||
// Callback para StateManager - Toggle gravedad ON/OFF para todas las pelotas
|
||||
void Engine::executeToggleGravityOnOff() {
|
||||
// Alternar entre activar/desactivar gravedad
|
||||
bool first_ball_gravity_enabled = (!scene_manager_->hasBalls() || scene_manager_->getFirstBall()->getGravityForce() > 0.0f);
|
||||
|
||||
@@ -1432,7 +1404,7 @@ void Engine::toggleGravityOnOff() {
|
||||
// SISTEMA DE MODO LOGO (Easter Egg - "Marca de Agua")
|
||||
// ============================================================================
|
||||
|
||||
// Entrar al Modo Logo (manual con tecla K o automático desde DEMO)
|
||||
// Método antiguo mantenido para código legacy de LOGO (será eliminado en Fase 9)
|
||||
void Engine::enterLogoMode(bool from_demo) {
|
||||
// Verificar mínimo de pelotas
|
||||
if (static_cast<int>(scene_manager_->getBallCount()) < LOGO_MODE_MIN_BALLS) {
|
||||
@@ -1490,18 +1462,64 @@ void Engine::enterLogoMode(bool from_demo) {
|
||||
logo_target_flip_percentage_ = 0.0f;
|
||||
logo_current_flip_count_ = 0;
|
||||
|
||||
// Guardar si entrada fue manual (tecla K) o automática (desde DEMO)
|
||||
logo_entered_manually_ = !from_demo;
|
||||
|
||||
// Cambiar a modo LOGO (guarda previous_app_mode_ automáticamente)
|
||||
setState(AppMode::LOGO);
|
||||
// La configuración de estado se maneja en StateManager
|
||||
}
|
||||
|
||||
// Salir del Modo Logo (volver a estado anterior o salir de DEMO)
|
||||
void Engine::exitLogoMode(bool return_to_demo) {
|
||||
if (state_manager_->getCurrentMode() != AppMode::LOGO) return;
|
||||
// Callbacks para StateManager - Solo configuración visual
|
||||
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)
|
||||
}
|
||||
|
||||
// Restaurar estado previo
|
||||
// Guardar estado previo (para restaurar al salir)
|
||||
logo_previous_theme_ = theme_manager_->getCurrentThemeIndex();
|
||||
logo_previous_texture_index_ = current_texture_index_;
|
||||
logo_previous_shape_scale_ = shape_scale_factor_;
|
||||
|
||||
// Buscar índice de textura "small"
|
||||
size_t small_index = current_texture_index_; // Por defecto mantener actual
|
||||
for (size_t i = 0; i < texture_names_.size(); i++) {
|
||||
if (texture_names_[i] == "small") {
|
||||
small_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Aplicar configuración fija del Modo Logo
|
||||
if (small_index != current_texture_index_) {
|
||||
current_texture_index_ = small_index;
|
||||
texture_ = textures_[current_texture_index_];
|
||||
int new_size = texture_->getWidth();
|
||||
current_ball_size_ = new_size;
|
||||
scene_manager_->updateBallTexture(texture_, new_size);
|
||||
}
|
||||
|
||||
// Cambiar a tema aleatorio entre: MONOCHROME, LAVENDER, CRIMSON, ESMERALDA
|
||||
int logo_themes[] = {5, 6, 7, 8}; // MONOCHROME, LAVENDER, CRIMSON, ESMERALDA
|
||||
int random_theme = logo_themes[rand() % 4];
|
||||
theme_manager_->switchToTheme(random_theme);
|
||||
|
||||
// Establecer escala a 120%
|
||||
shape_scale_factor_ = LOGO_MODE_SHAPE_SCALE;
|
||||
clampShapeScale();
|
||||
|
||||
// Activar PNG_SHAPE (el logo)
|
||||
activateShapeInternal(ShapeType::PNG_SHAPE);
|
||||
|
||||
// Configurar PNG_SHAPE en modo LOGO (flip intervals más largos)
|
||||
if (active_shape_) {
|
||||
PNGShape* png_shape = dynamic_cast<PNGShape*>(active_shape_.get());
|
||||
if (png_shape) {
|
||||
png_shape->setLogoMode(true);
|
||||
png_shape->resetFlipCount(); // Resetear contador de flips
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::executeExitLogoMode() {
|
||||
// Restaurar estado visual previo
|
||||
theme_manager_->switchToTheme(logo_previous_theme_);
|
||||
|
||||
if (logo_previous_texture_index_ != current_texture_index_ &&
|
||||
@@ -1525,16 +1543,6 @@ void Engine::exitLogoMode(bool return_to_demo) {
|
||||
}
|
||||
}
|
||||
|
||||
// Resetear flag de entrada manual
|
||||
logo_entered_manually_ = false;
|
||||
|
||||
if (!return_to_demo) {
|
||||
// Salida manual (tecla K): volver a MANUAL
|
||||
setState(AppMode::SANDBOX);
|
||||
} else {
|
||||
// Volver al modo previo (DEMO o DEMO_LITE)
|
||||
setState(previous_app_mode_);
|
||||
|
||||
// Si la figura activa es PNG_SHAPE, cambiar a otra figura aleatoria
|
||||
if (current_shape_type_ == ShapeType::PNG_SHAPE) {
|
||||
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::LISSAJOUS, ShapeType::HELIX,
|
||||
@@ -1542,7 +1550,6 @@ void Engine::exitLogoMode(bool return_to_demo) {
|
||||
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||
activateShapeInternal(shapes[rand() % 8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle manual del Modo Logo (tecla K)
|
||||
|
||||
@@ -70,6 +70,17 @@ class Engine {
|
||||
void toggleDemoLiteMode();
|
||||
void toggleLogoMode();
|
||||
|
||||
// === Métodos públicos para StateManager (callbacks) ===
|
||||
// NOTA FASE 8: StateManager necesita llamar a Engine para ejecutar acciones
|
||||
// que requieren acceso a múltiples componentes (SceneManager, ThemeManager, etc.)
|
||||
// TODO FASE 9: Mover lógica completa a StateManager eliminando estos callbacks
|
||||
void performLogoAction(bool logo_waiting_for_flip);
|
||||
void executeDemoAction(bool is_lite);
|
||||
void executeRandomizeOnDemoStart(bool is_lite);
|
||||
void executeToggleGravityOnOff();
|
||||
void executeEnterLogoMode(size_t ball_count);
|
||||
void executeExitLogoMode();
|
||||
|
||||
private:
|
||||
// === Componentes del sistema (Composición) ===
|
||||
std::unique_ptr<InputHandler> input_handler_; // Manejo de entradas SDL
|
||||
|
||||
@@ -38,15 +38,84 @@ void StateManager::setLogoPreviousState(int theme, size_t texture_index, float s
|
||||
logo_previous_shape_scale_ = shape_scale;
|
||||
}
|
||||
|
||||
// TODO: Implementar métodos completos
|
||||
// Por ahora, stubs vacíos para que compile
|
||||
// ===========================================================================
|
||||
// ACTUALIZACIÓN DE ESTADOS - Migrado desde Engine::updateDemoMode()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::update(float delta_time, float shape_convergence, Shape* active_shape) {
|
||||
// Delegar a Engine temporalmente - La lógica compleja queda en Engine por ahora
|
||||
// Este es un wrapper que permite refactorizar gradualmente
|
||||
// Verificar si algún modo demo está activo (DEMO, DEMO_LITE o LOGO)
|
||||
if (current_app_mode_ == AppMode::SANDBOX) return;
|
||||
|
||||
// Actualizar timer
|
||||
demo_timer_ += delta_time;
|
||||
|
||||
// Determinar si es hora de ejecutar acción (depende del modo)
|
||||
bool should_trigger = false;
|
||||
|
||||
if (current_app_mode_ == AppMode::LOGO) {
|
||||
// LOGO MODE: Dos caminos posibles
|
||||
if (logo_waiting_for_flip_) {
|
||||
// CAMINO B: Esperando a que ocurran flips
|
||||
// Obtener referencia a PNGShape si está activa
|
||||
PNGShape* png_shape = dynamic_cast<PNGShape*>(active_shape);
|
||||
|
||||
if (png_shape) {
|
||||
int current_flip_count = png_shape->getFlipCount();
|
||||
|
||||
// Detectar nuevo flip completado
|
||||
if (current_flip_count > logo_current_flip_count_) {
|
||||
logo_current_flip_count_ = current_flip_count;
|
||||
}
|
||||
|
||||
// Si estamos EN o DESPUÉS del flip objetivo
|
||||
// +1 porque queremos actuar DURANTE el flip N, no después de completarlo
|
||||
if (logo_current_flip_count_ + 1 >= logo_target_flip_number_) {
|
||||
// Monitorear progreso del flip actual
|
||||
if (png_shape->isFlipping()) {
|
||||
float flip_progress = png_shape->getFlipProgress();
|
||||
if (flip_progress >= logo_target_flip_percentage_) {
|
||||
should_trigger = true; // ¡Trigger durante el flip!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// CAMINO A: Esperar convergencia + tiempo (comportamiento original)
|
||||
bool min_time_reached = demo_timer_ >= logo_min_time_;
|
||||
bool max_time_reached = demo_timer_ >= logo_max_time_;
|
||||
bool convergence_ok = shape_convergence >= logo_convergence_threshold_;
|
||||
|
||||
should_trigger = (min_time_reached && convergence_ok) || max_time_reached;
|
||||
}
|
||||
} else {
|
||||
// DEMO/DEMO_LITE: Timer simple como antes
|
||||
should_trigger = demo_timer_ >= demo_next_action_time_;
|
||||
}
|
||||
|
||||
// Si es hora de ejecutar acción
|
||||
if (should_trigger) {
|
||||
// MODO LOGO: Sistema de acciones variadas con gravedad dinámica
|
||||
if (current_app_mode_ == AppMode::LOGO) {
|
||||
// Llamar a Engine para ejecutar acciones de LOGO
|
||||
// TODO FASE 9: Mover lógica de acciones LOGO desde Engine a StateManager
|
||||
if (engine_) {
|
||||
// Engine mantiene la implementación de updateDemoMode()
|
||||
// StateManager solo coordina el estado
|
||||
engine_->performLogoAction(logo_waiting_for_flip_);
|
||||
}
|
||||
}
|
||||
// MODO DEMO/DEMO_LITE: Acciones normales
|
||||
else {
|
||||
bool is_lite = (current_app_mode_ == AppMode::DEMO_LITE);
|
||||
performDemoAction(is_lite);
|
||||
|
||||
// Resetear timer y calcular próximo intervalo aleatorio
|
||||
demo_timer_ = 0.0f;
|
||||
|
||||
// Usar intervalos diferentes según modo
|
||||
float interval_min = is_lite ? DEMO_LITE_ACTION_INTERVAL_MIN : DEMO_ACTION_INTERVAL_MIN;
|
||||
float interval_max = is_lite ? DEMO_LITE_ACTION_INTERVAL_MAX : DEMO_ACTION_INTERVAL_MAX;
|
||||
float interval_range = interval_max - interval_min;
|
||||
demo_next_action_time_ = interval_min + (rand() % 1000) / 1000.0f * interval_range;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +134,27 @@ void StateManager::setState(AppMode new_mode, int current_screen_width, int curr
|
||||
|
||||
// Resetear timer al cambiar modo
|
||||
demo_timer_ = 0.0f;
|
||||
|
||||
// Configurar timer de demo según el modo
|
||||
if (new_mode == AppMode::DEMO || new_mode == AppMode::DEMO_LITE || new_mode == AppMode::LOGO) {
|
||||
float min_interval, max_interval;
|
||||
|
||||
if (new_mode == AppMode::LOGO) {
|
||||
// Escalar tiempos con resolución (720p como base)
|
||||
float resolution_scale = current_screen_height / 720.0f;
|
||||
logo_min_time_ = LOGO_ACTION_INTERVAL_MIN * resolution_scale;
|
||||
logo_max_time_ = LOGO_ACTION_INTERVAL_MAX * resolution_scale;
|
||||
|
||||
min_interval = logo_min_time_;
|
||||
max_interval = logo_max_time_;
|
||||
} else {
|
||||
bool is_lite = (new_mode == AppMode::DEMO_LITE);
|
||||
min_interval = is_lite ? DEMO_LITE_ACTION_INTERVAL_MIN : DEMO_ACTION_INTERVAL_MIN;
|
||||
max_interval = is_lite ? DEMO_LITE_ACTION_INTERVAL_MAX : DEMO_ACTION_INTERVAL_MAX;
|
||||
}
|
||||
|
||||
demo_next_action_time_ = min_interval + (rand() % 1000) / 1000.0f * (max_interval - min_interval);
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::toggleDemoMode(int current_screen_width, int current_screen_height) {
|
||||
@@ -72,6 +162,7 @@ void StateManager::toggleDemoMode(int current_screen_width, int current_screen_h
|
||||
setState(AppMode::SANDBOX, current_screen_width, current_screen_height);
|
||||
} else {
|
||||
setState(AppMode::DEMO, current_screen_width, current_screen_height);
|
||||
randomizeOnDemoStart(false); // Randomizar estado al entrar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,34 +171,106 @@ void StateManager::toggleDemoLiteMode(int current_screen_width, int current_scre
|
||||
setState(AppMode::SANDBOX, current_screen_width, current_screen_height);
|
||||
} else {
|
||||
setState(AppMode::DEMO_LITE, current_screen_width, current_screen_height);
|
||||
randomizeOnDemoStart(true); // Randomizar estado al entrar
|
||||
}
|
||||
}
|
||||
|
||||
void StateManager::toggleLogoMode(int current_screen_width, int current_screen_height, size_t ball_count) {
|
||||
if (current_app_mode_ == AppMode::LOGO) {
|
||||
setState(AppMode::SANDBOX, current_screen_width, current_screen_height);
|
||||
exitLogoMode(false); // Salir de LOGO manualmente
|
||||
} else {
|
||||
setState(AppMode::LOGO, current_screen_width, current_screen_height);
|
||||
logo_entered_manually_ = true;
|
||||
enterLogoMode(false, current_screen_width, current_screen_height, ball_count); // Entrar manualmente
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// ACCIONES DE DEMO - Migrado desde Engine::performDemoAction()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::performDemoAction(bool is_lite) {
|
||||
// TODO: Migrar performDemoAction()
|
||||
// ============================================
|
||||
// SALTO AUTOMÁTICO A LOGO MODE (Easter Egg)
|
||||
// ============================================
|
||||
|
||||
// Obtener información necesaria desde Engine via callbacks
|
||||
// (En el futuro, se podría pasar como parámetros al método)
|
||||
if (!engine_) return;
|
||||
|
||||
// TODO FASE 9: Eliminar callbacks a Engine y pasar parámetros necesarios
|
||||
|
||||
// Por ahora, delegar las acciones DEMO completas a Engine
|
||||
// ya que necesitan acceso a múltiples componentes (SceneManager, ThemeManager, etc.)
|
||||
engine_->executeDemoAction(is_lite);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// RANDOMIZACIÓN AL INICIAR DEMO - Migrado desde Engine::randomizeOnDemoStart()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::randomizeOnDemoStart(bool is_lite) {
|
||||
// TODO: Migrar randomizeOnDemoStart()
|
||||
// Delegar a Engine para randomización completa
|
||||
// TODO FASE 9: Implementar lógica completa aquí
|
||||
if (engine_) {
|
||||
engine_->executeRandomizeOnDemoStart(is_lite);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// TOGGLE GRAVEDAD (para DEMO) - Migrado desde Engine::toggleGravityOnOff()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::toggleGravityOnOff() {
|
||||
// TODO: Migrar toggleGravityOnOff()
|
||||
// Delegar a Engine temporalmente
|
||||
if (engine_) {
|
||||
engine_->executeToggleGravityOnOff();
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// ENTRAR AL MODO LOGO - Migrado desde Engine::enterLogoMode()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::enterLogoMode(bool from_demo, int current_screen_width, int current_screen_height, size_t ball_count) {
|
||||
// TODO: Migrar enterLogoMode()
|
||||
// Guardar si entrada fue manual (tecla K) o automática (desde DEMO)
|
||||
logo_entered_manually_ = !from_demo;
|
||||
|
||||
// Resetear variables de espera de flips
|
||||
logo_waiting_for_flip_ = false;
|
||||
logo_target_flip_number_ = 0;
|
||||
logo_target_flip_percentage_ = 0.0f;
|
||||
logo_current_flip_count_ = 0;
|
||||
|
||||
// Cambiar a modo LOGO (guarda previous_app_mode_ automáticamente)
|
||||
setState(AppMode::LOGO, current_screen_width, current_screen_height);
|
||||
|
||||
// Delegar configuración visual a Engine
|
||||
// TODO FASE 9: Mover configuración completa aquí
|
||||
if (engine_) {
|
||||
engine_->executeEnterLogoMode(ball_count);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// SALIR DEL MODO LOGO - Migrado desde Engine::exitLogoMode()
|
||||
// ===========================================================================
|
||||
|
||||
void StateManager::exitLogoMode(bool return_to_demo) {
|
||||
// TODO: Migrar exitLogoMode()
|
||||
if (current_app_mode_ != AppMode::LOGO) return;
|
||||
|
||||
// Resetear flag de entrada manual
|
||||
logo_entered_manually_ = false;
|
||||
|
||||
// Delegar restauración visual a Engine
|
||||
// TODO FASE 9: Mover lógica completa aquí
|
||||
if (engine_) {
|
||||
engine_->executeExitLogoMode();
|
||||
}
|
||||
|
||||
if (!return_to_demo) {
|
||||
// Salida manual (tecla K): volver a SANDBOX
|
||||
setState(AppMode::SANDBOX, 0, 0);
|
||||
} else {
|
||||
// Volver al modo previo (DEMO o DEMO_LITE)
|
||||
current_app_mode_ = previous_app_mode_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,21 @@ class StateManager {
|
||||
*/
|
||||
void setLogoPreviousState(int theme, size_t texture_index, float shape_scale);
|
||||
|
||||
/**
|
||||
* @brief Entra al modo LOGO (público para permitir salto automático desde DEMO)
|
||||
* @param from_demo true si viene desde DEMO, false si es manual
|
||||
* @param current_screen_width Ancho de pantalla
|
||||
* @param current_screen_height Alto de pantalla
|
||||
* @param ball_count Número de bolas
|
||||
*/
|
||||
void enterLogoMode(bool from_demo, int current_screen_width, int current_screen_height, size_t ball_count);
|
||||
|
||||
/**
|
||||
* @brief Sale del modo LOGO (público para permitir salida manual)
|
||||
* @param return_to_demo true si debe volver a DEMO/DEMO_LITE
|
||||
*/
|
||||
void exitLogoMode(bool return_to_demo);
|
||||
|
||||
private:
|
||||
// === Referencia al Engine (callback) ===
|
||||
Engine* engine_;
|
||||
@@ -173,19 +188,4 @@ class StateManager {
|
||||
* @brief Toggle de gravedad ON/OFF (para DEMO)
|
||||
*/
|
||||
void toggleGravityOnOff();
|
||||
|
||||
/**
|
||||
* @brief Entra al modo LOGO
|
||||
* @param from_demo true si viene desde DEMO, false si es manual
|
||||
* @param current_screen_width Ancho de pantalla
|
||||
* @param current_screen_height Alto de pantalla
|
||||
* @param ball_count Número de bolas
|
||||
*/
|
||||
void enterLogoMode(bool from_demo, int current_screen_width, int current_screen_height, size_t ball_count);
|
||||
|
||||
/**
|
||||
* @brief Sale del modo LOGO
|
||||
* @param return_to_demo true si debe volver a DEMO/DEMO_LITE
|
||||
*/
|
||||
void exitLogoMode(bool return_to_demo);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user