Files
vibe3_physics/source/state/state_manager.h
Sergio Valor e7dc8f6d13 feat: añadir cambio de dirección de gravedad en modo LOGO
El modo LOGO ahora incluye cambios automáticos de dirección de
gravedad como parte de sus variaciones, aumentando la diversidad
visual de la demostración.

Cambios:
- Nueva acción en modo LOGO (PHYSICS): cambiar dirección gravedad (16%)
- Rebalanceo de probabilidades existentes:
  • PHYSICS → SHAPE: 60% → 50%
  • Gravedad ON: 20% → 18%
  • Gravedad OFF: 20% → 16%
  • Dirección gravedad: nuevo 16%
- Al cambiar dirección, se fuerza gravedad ON para visibilidad

Antes el modo LOGO solo alternaba entre figura/física y gravedad
on/off, pero nunca cambiaba la dirección. Ahora tiene las mismas
capacidades de variación que los modos DEMO y DEMO_LITE.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:11:22 +02:00

197 lines
6.5 KiB
C++

#pragma once
#include <SDL3/SDL_stdinc.h> // for Uint64
#include <cstddef> // for size_t
#include "../defines.h" // for AppMode, ShapeType, GravityDirection
// Forward declarations
class Engine;
class Shape;
class PNGShape;
/**
* @class StateManager
* @brief Gestiona los estados de aplicación (SANDBOX/DEMO/DEMO_LITE/LOGO)
*
* Responsabilidad única: Máquina de estados y lógica de modos automáticos
*
* Características:
* - Control de modo DEMO (auto-play completo)
* - Control de modo DEMO_LITE (solo física/figuras)
* - Control de modo LOGO (easter egg con convergencia)
* - Timers y triggers automáticos
* - Sistema de convergencia y espera de flips
* - Callbacks al Engine para ejecutar acciones
*/
class StateManager {
public:
/**
* @brief Constructor
*/
StateManager();
/**
* @brief Destructor
*/
~StateManager();
/**
* @brief Inicializa el StateManager con referencia al Engine
* @param engine Puntero al Engine (para callbacks)
*/
void initialize(Engine* engine);
/**
* @brief Actualiza la máquina de estados (timers, triggers, acciones)
* @param delta_time Delta time para timers
* @param shape_convergence Convergencia actual de la forma (0.0-1.0)
* @param active_shape Puntero a la forma activa (para flip detection)
*/
void update(float delta_time, float shape_convergence, Shape* active_shape);
/**
* @brief Cambia el estado de aplicación
* @param new_mode Nuevo modo (SANDBOX/DEMO/DEMO_LITE/LOGO)
* @param current_screen_width Ancho de pantalla (para escalar tiempos)
* @param current_screen_height Alto de pantalla (para escalar tiempos)
*/
void setState(AppMode new_mode, int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo DEMO completo (tecla L)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
*/
void toggleDemoMode(int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo DEMO_LITE (tecla L x2)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
*/
void toggleDemoLiteMode(int current_screen_width, int current_screen_height);
/**
* @brief Toggle del modo LOGO (tecla K)
* @param current_screen_width Ancho de pantalla
* @param current_screen_height Alto de pantalla
* @param ball_count Número de bolas actual
*/
void toggleLogoMode(int current_screen_width, int current_screen_height, size_t ball_count);
// === Getters ===
/**
* @brief Obtiene el modo actual
*/
AppMode getCurrentMode() const { return current_app_mode_; }
/**
* @brief Obtiene el modo previo (antes de LOGO)
*/
AppMode getPreviousMode() const { return previous_app_mode_; }
/**
* @brief Verifica si LOGO está activo
*/
bool isLogoModeActive() const { return current_app_mode_ == AppMode::LOGO; }
/**
* @brief Verifica si DEMO (completo o lite) está activo
*/
bool isDemoModeActive() const {
return current_app_mode_ == AppMode::DEMO || current_app_mode_ == AppMode::DEMO_LITE;
}
/**
* @brief Obtiene índice de tema guardado (para restaurar al salir de LOGO)
*/
int getLogoPreviousTheme() const { return logo_previous_theme_; }
/**
* @brief Obtiene índice de textura guardada (para restaurar al salir de LOGO)
*/
size_t getLogoPreviousTextureIndex() const { return logo_previous_texture_index_; }
/**
* @brief Obtiene escala de forma guardada (para restaurar al salir de LOGO)
*/
float getLogoPreviousShapeScale() const { return logo_previous_shape_scale_; }
/**
* @brief Obtiene si LOGO fue activado manualmente (tecla K) o automáticamente (desde DEMO)
*/
bool getLogoEnteredManually() const { return logo_entered_manually_; }
/**
* @brief Establece valores previos de LOGO (llamado por Engine antes de entrar)
*/
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_;
// === Estado de aplicación ===
AppMode current_app_mode_;
AppMode previous_app_mode_;
// === Sistema DEMO (timers) ===
float demo_timer_;
float demo_next_action_time_;
// === Sistema LOGO (convergencia) ===
float logo_convergence_threshold_;
float logo_min_time_;
float logo_max_time_;
// === Sistema LOGO (espera de flips) ===
bool logo_waiting_for_flip_;
int logo_target_flip_number_;
float logo_target_flip_percentage_;
int logo_current_flip_count_;
// === Control de entrada LOGO ===
bool logo_entered_manually_;
// === Estado previo LOGO (restauración) ===
int logo_previous_theme_;
size_t logo_previous_texture_index_;
float logo_previous_shape_scale_;
// === Métodos privados ===
/**
* @brief Ejecuta una acción del modo DEMO
* @param is_lite true si es DEMO_LITE, false si es DEMO completo
*/
void performDemoAction(bool is_lite);
/**
* @brief Randomiza estado al entrar a modo DEMO
* @param is_lite true si es DEMO_LITE, false si es DEMO completo
*/
void randomizeOnDemoStart(bool is_lite);
/**
* @brief Toggle de gravedad ON/OFF (para DEMO)
*/
void toggleGravityOnOff();
};