Mejorar DEMO MODE + Añadir DEMO LITE MODE (Tecla L)
MEJORAS DEMO MODE (Tecla D): ✅ **Randomización completa al activar**: escenario, tema, sprite, física/figura, gravedad, profundidad, escala ✅ **Excluye escenarios problemáticos**: 1, 50K, 100K pelotas (índices 0, 6, 7) ✅ **Nuevas acciones dinámicas**: - Toggle gravedad ON/OFF (8%) - Toggle física ↔ figura (12%) - Re-generar misma figura (8%) ✅ **Intervalos más rápidos**: 2-6s (antes 3-8s) ✅ **SIN TEXTOS** durante demo (solo "DEMO MODE") ✅ **Pesos rebalanceados**: Más variedad y dinamismo NUEVO: DEMO LITE MODE (Tecla L): ✅ **Solo física/figuras**: NO cambia escenario, tema, sprite, profundidad, escala ✅ **Randomización inicial lite**: física/figura + gravedad ✅ **Acciones lite**: - Cambiar dirección gravedad (25%) - Toggle gravedad ON/OFF (20%) - Activar figura 3D (25%) - Toggle física ↔ figura (20%) - Aplicar impulso (10%) ✅ **Intervalos ultra-rápidos**: 1.5-4s ✅ **Display visual**: "DEMO LITE" en azul claro (128, 200, 255) ✅ **Mutuamente excluyente**: D y L no pueden estar activos a la vez CAMBIOS TÉCNICOS: - Nuevas constantes en defines.h: DEMO_LITE_* (intervalos + pesos) - Nuevos métodos: * `randomizeOnDemoStart(bool is_lite)` - Randomización inicial * `toggleGravityOnOff()` - Activar/desactivar gravedad - `performDemoAction()` ahora recibe parámetro `is_lite` - Suprimidos textos en: setText(), startThemeTransition(), switchTexture(), toggleShapeMode(), activateShape() - DEMO MODE nunca cambia dimensiones de ventana ni modo pantalla 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -153,19 +153,34 @@ constexpr float SHAPE_SCALE_MAX = 3.0f; // Escala máxima (300%)
|
|||||||
constexpr float SHAPE_SCALE_STEP = 0.1f; // Incremento por pulsación
|
constexpr float SHAPE_SCALE_STEP = 0.1f; // Incremento por pulsación
|
||||||
constexpr float SHAPE_SCALE_DEFAULT = 1.0f; // Escala por defecto (100%)
|
constexpr float SHAPE_SCALE_DEFAULT = 1.0f; // Escala por defecto (100%)
|
||||||
|
|
||||||
// Configuración de Modo DEMO (auto-play)
|
// Configuración de Modo DEMO (auto-play completo)
|
||||||
constexpr float DEMO_ACTION_INTERVAL_MIN = 3.0f; // Tiempo mínimo entre acciones (segundos)
|
constexpr float DEMO_ACTION_INTERVAL_MIN = 2.0f; // Tiempo mínimo entre acciones (segundos)
|
||||||
constexpr float DEMO_ACTION_INTERVAL_MAX = 8.0f; // Tiempo máximo entre acciones (segundos)
|
constexpr float DEMO_ACTION_INTERVAL_MAX = 6.0f; // Tiempo máximo entre acciones (segundos)
|
||||||
|
|
||||||
// Pesos de probabilidad para cada tipo de acción (valores relativos, se normalizan)
|
// Pesos de probabilidad DEMO MODE (valores relativos, se normalizan)
|
||||||
constexpr int DEMO_WEIGHT_GRAVITY = 15; // Cambiar dirección gravedad (15%)
|
constexpr int DEMO_WEIGHT_GRAVITY_DIR = 10; // Cambiar dirección gravedad (10%)
|
||||||
constexpr int DEMO_WEIGHT_SHAPE = 25; // Activar figura 3D (25%)
|
constexpr int DEMO_WEIGHT_GRAVITY_TOGGLE = 8; // Toggle gravedad ON/OFF (8%)
|
||||||
constexpr int DEMO_WEIGHT_THEME = 20; // Cambiar tema de colores (20%)
|
constexpr int DEMO_WEIGHT_SHAPE = 20; // Activar figura 3D (20%)
|
||||||
constexpr int DEMO_WEIGHT_SCENARIO = 15; // Cambiar número de pelotas (15%)
|
constexpr int DEMO_WEIGHT_TOGGLE_PHYSICS = 12; // Toggle física ↔ figura (12%)
|
||||||
|
constexpr int DEMO_WEIGHT_REGENERATE_SHAPE = 8; // Re-generar misma figura (8%)
|
||||||
|
constexpr int DEMO_WEIGHT_THEME = 15; // Cambiar tema de colores (15%)
|
||||||
|
constexpr int DEMO_WEIGHT_SCENARIO = 10; // Cambiar número de pelotas (10%)
|
||||||
constexpr int DEMO_WEIGHT_IMPULSE = 10; // Aplicar impulso (SPACE) (10%)
|
constexpr int DEMO_WEIGHT_IMPULSE = 10; // Aplicar impulso (SPACE) (10%)
|
||||||
constexpr int DEMO_WEIGHT_DEPTH_ZOOM = 5; // Toggle profundidad (5%)
|
constexpr int DEMO_WEIGHT_DEPTH_ZOOM = 3; // Toggle profundidad (3%)
|
||||||
constexpr int DEMO_WEIGHT_SHAPE_SCALE = 5; // Cambiar escala figura (5%)
|
constexpr int DEMO_WEIGHT_SHAPE_SCALE = 2; // Cambiar escala figura (2%)
|
||||||
constexpr int DEMO_WEIGHT_SPRITE = 5; // Cambiar sprite (5%)
|
constexpr int DEMO_WEIGHT_SPRITE = 2; // Cambiar sprite (2%)
|
||||||
// TOTAL: 100 (se pueden ajustar para priorizar acciones)
|
// TOTAL: 100
|
||||||
|
|
||||||
|
// Configuración de Modo DEMO LITE (solo física/figuras)
|
||||||
|
constexpr float DEMO_LITE_ACTION_INTERVAL_MIN = 1.5f; // Más rápido que demo completo
|
||||||
|
constexpr float DEMO_LITE_ACTION_INTERVAL_MAX = 4.0f;
|
||||||
|
|
||||||
|
// Pesos de probabilidad DEMO LITE (solo física/figuras, sin cambios de escenario/tema)
|
||||||
|
constexpr int DEMO_LITE_WEIGHT_GRAVITY_DIR = 25; // Cambiar dirección gravedad (25%)
|
||||||
|
constexpr int DEMO_LITE_WEIGHT_GRAVITY_TOGGLE = 20;// Toggle gravedad ON/OFF (20%)
|
||||||
|
constexpr int DEMO_LITE_WEIGHT_SHAPE = 25; // Activar figura 3D (25%)
|
||||||
|
constexpr int DEMO_LITE_WEIGHT_TOGGLE_PHYSICS = 20;// Toggle física ↔ figura (20%)
|
||||||
|
constexpr int DEMO_LITE_WEIGHT_IMPULSE = 10; // Aplicar impulso (10%)
|
||||||
|
// TOTAL: 100
|
||||||
|
|
||||||
constexpr float PI = 3.14159265358979323846f; // Constante PI
|
constexpr float PI = 3.14159265358979323846f; // Constante PI
|
||||||
@@ -469,11 +469,17 @@ void Engine::handleEvents() {
|
|||||||
toggleIntegerScaling();
|
toggleIntegerScaling();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Toggle Modo DEMO (auto-play)
|
// Toggle Modo DEMO COMPLETO (auto-play)
|
||||||
case SDLK_D:
|
case SDLK_D:
|
||||||
demo_mode_enabled_ = !demo_mode_enabled_;
|
demo_mode_enabled_ = !demo_mode_enabled_;
|
||||||
if (demo_mode_enabled_) {
|
if (demo_mode_enabled_) {
|
||||||
// Al activar: inicializar timer con primer intervalo aleatorio
|
// Desactivar demo lite si estaba activo (mutuamente excluyentes)
|
||||||
|
demo_lite_enabled_ = false;
|
||||||
|
|
||||||
|
// Randomizar TODO al activar
|
||||||
|
randomizeOnDemoStart(false);
|
||||||
|
|
||||||
|
// Inicializar timer con primer intervalo aleatorio
|
||||||
demo_timer_ = 0.0f;
|
demo_timer_ = 0.0f;
|
||||||
float interval_range = DEMO_ACTION_INTERVAL_MAX - DEMO_ACTION_INTERVAL_MIN;
|
float interval_range = DEMO_ACTION_INTERVAL_MAX - DEMO_ACTION_INTERVAL_MIN;
|
||||||
demo_next_action_time_ = DEMO_ACTION_INTERVAL_MIN + (rand() % 1000) / 1000.0f * interval_range;
|
demo_next_action_time_ = DEMO_ACTION_INTERVAL_MIN + (rand() % 1000) / 1000.0f * interval_range;
|
||||||
@@ -489,6 +495,33 @@ void Engine::handleEvents() {
|
|||||||
text_init_time_ = SDL_GetTicks();
|
text_init_time_ = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Toggle Modo DEMO LITE (solo física/figuras)
|
||||||
|
case SDLK_L:
|
||||||
|
demo_lite_enabled_ = !demo_lite_enabled_;
|
||||||
|
if (demo_lite_enabled_) {
|
||||||
|
// Desactivar demo completo si estaba activo (mutuamente excluyentes)
|
||||||
|
demo_mode_enabled_ = false;
|
||||||
|
|
||||||
|
// Randomizar solo física/figura (mantiene escenario y tema)
|
||||||
|
randomizeOnDemoStart(true);
|
||||||
|
|
||||||
|
// Inicializar timer con primer intervalo aleatorio (más rápido)
|
||||||
|
demo_timer_ = 0.0f;
|
||||||
|
float interval_range = DEMO_LITE_ACTION_INTERVAL_MAX - DEMO_LITE_ACTION_INTERVAL_MIN;
|
||||||
|
demo_next_action_time_ = DEMO_LITE_ACTION_INTERVAL_MIN + (rand() % 1000) / 1000.0f * interval_range;
|
||||||
|
|
||||||
|
// Mostrar texto de activación
|
||||||
|
text_ = "DEMO LITE ON";
|
||||||
|
show_text_ = true;
|
||||||
|
text_init_time_ = SDL_GetTicks();
|
||||||
|
} else {
|
||||||
|
// Al desactivar: mostrar texto
|
||||||
|
text_ = "DEMO LITE OFF";
|
||||||
|
show_text_ = true;
|
||||||
|
text_init_time_ = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -629,13 +662,19 @@ void Engine::render() {
|
|||||||
dbg_print(8, 72, mode_text.c_str(), 0, 255, 128); // Verde claro para modo
|
dbg_print(8, 72, mode_text.c_str(), 0, 255, 128); // Verde claro para modo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mostrar indicador "DEMO MODE" permanente cuando está activo (independiente de show_debug_)
|
// Mostrar indicador "DEMO MODE" o "DEMO LITE" permanente (independiente de show_debug_)
|
||||||
if (demo_mode_enabled_) {
|
if (demo_mode_enabled_) {
|
||||||
// Centrar texto horizontalmente
|
// Centrar texto horizontalmente
|
||||||
const char* demo_text = "DEMO MODE";
|
const char* demo_text = "DEMO MODE";
|
||||||
int demo_text_width = static_cast<int>(strlen(demo_text) * 8); // 8 píxeles por carácter
|
int demo_text_width = static_cast<int>(strlen(demo_text) * 8); // 8 píxeles por carácter
|
||||||
int demo_x = (current_screen_width_ - demo_text_width) / 2;
|
int demo_x = (current_screen_width_ - demo_text_width) / 2;
|
||||||
dbg_print(demo_x, 8, demo_text, 255, 128, 0); // Naranja brillante
|
dbg_print(demo_x, 8, demo_text, 255, 128, 0); // Naranja brillante
|
||||||
|
} else if (demo_lite_enabled_) {
|
||||||
|
// Centrar texto horizontalmente
|
||||||
|
const char* demo_lite_text = "DEMO LITE";
|
||||||
|
int demo_lite_text_width = static_cast<int>(strlen(demo_lite_text) * 8);
|
||||||
|
int demo_lite_x = (current_screen_width_ - demo_lite_text_width) / 2;
|
||||||
|
dbg_print(demo_lite_x, 8, demo_lite_text, 128, 200, 255); // Azul claro
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(renderer_);
|
SDL_RenderPresent(renderer_);
|
||||||
@@ -675,6 +714,9 @@ void Engine::initBalls(int value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::setText() {
|
void Engine::setText() {
|
||||||
|
// Suprimir textos durante modos demo
|
||||||
|
if (demo_mode_enabled_ || demo_lite_enabled_) return;
|
||||||
|
|
||||||
int num_balls = test_.at(scenario_);
|
int num_balls = test_.at(scenario_);
|
||||||
if (num_balls == 1) {
|
if (num_balls == 1) {
|
||||||
text_ = "1 PELOTA";
|
text_ = "1 PELOTA";
|
||||||
@@ -1167,12 +1209,14 @@ void Engine::startThemeTransition(ColorTheme new_theme) {
|
|||||||
transitioning_ = true;
|
transitioning_ = true;
|
||||||
transition_progress_ = 0.0f;
|
transition_progress_ = 0.0f;
|
||||||
|
|
||||||
// Mostrar nombre del tema (igual que selección directa con KP_1-6)
|
// Mostrar nombre del tema (solo si NO estamos en modo demo)
|
||||||
ThemeColors& theme = themes_[static_cast<int>(new_theme)];
|
if (!demo_mode_enabled_ && !demo_lite_enabled_) {
|
||||||
text_ = theme.name_es;
|
ThemeColors& theme = themes_[static_cast<int>(new_theme)];
|
||||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
text_ = theme.name_es;
|
||||||
show_text_ = true;
|
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||||
text_init_time_ = SDL_GetTicks();
|
show_text_ = true;
|
||||||
|
text_init_time_ = SDL_GetTicks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color Engine::getInterpolatedColor(size_t ball_index) const {
|
Color Engine::getInterpolatedColor(size_t ball_index) const {
|
||||||
@@ -1199,110 +1243,279 @@ Color Engine::getInterpolatedColor(size_t ball_index) const {
|
|||||||
|
|
||||||
// Sistema de Modo DEMO (auto-play)
|
// Sistema de Modo DEMO (auto-play)
|
||||||
void Engine::updateDemoMode() {
|
void Engine::updateDemoMode() {
|
||||||
if (!demo_mode_enabled_) return;
|
// Verificar si algún modo está activo
|
||||||
|
bool is_demo_active = demo_mode_enabled_ || demo_lite_enabled_;
|
||||||
|
if (!is_demo_active) return;
|
||||||
|
|
||||||
// Actualizar timer
|
// Actualizar timer
|
||||||
demo_timer_ += delta_time_;
|
demo_timer_ += delta_time_;
|
||||||
|
|
||||||
// Si es hora de ejecutar acción
|
// Si es hora de ejecutar acción
|
||||||
if (demo_timer_ >= demo_next_action_time_) {
|
if (demo_timer_ >= demo_next_action_time_) {
|
||||||
performDemoAction();
|
// Ejecutar acción según modo activo
|
||||||
|
bool is_lite = demo_lite_enabled_;
|
||||||
|
performDemoAction(is_lite);
|
||||||
|
|
||||||
// Resetear timer y calcular próximo intervalo aleatorio
|
// Resetear timer y calcular próximo intervalo aleatorio
|
||||||
demo_timer_ = 0.0f;
|
demo_timer_ = 0.0f;
|
||||||
float interval_range = DEMO_ACTION_INTERVAL_MAX - DEMO_ACTION_INTERVAL_MIN;
|
|
||||||
demo_next_action_time_ = DEMO_ACTION_INTERVAL_MIN + (rand() % 1000) / 1000.0f * interval_range;
|
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::performDemoAction() {
|
void Engine::performDemoAction(bool is_lite) {
|
||||||
// Calcular suma total de pesos
|
int TOTAL_WEIGHT;
|
||||||
const int TOTAL_WEIGHT = DEMO_WEIGHT_GRAVITY + DEMO_WEIGHT_SHAPE + DEMO_WEIGHT_THEME
|
int random_value;
|
||||||
+ DEMO_WEIGHT_SCENARIO + DEMO_WEIGHT_IMPULSE + DEMO_WEIGHT_DEPTH_ZOOM
|
|
||||||
+ DEMO_WEIGHT_SHAPE_SCALE + DEMO_WEIGHT_SPRITE;
|
|
||||||
|
|
||||||
// Generar número aleatorio entre 0 y TOTAL_WEIGHT
|
|
||||||
int random_value = rand() % TOTAL_WEIGHT;
|
|
||||||
|
|
||||||
// Determinar acción según pesos acumulados
|
|
||||||
int accumulated_weight = 0;
|
int accumulated_weight = 0;
|
||||||
|
|
||||||
// Acción: Cambiar gravedad (15%)
|
if (is_lite) {
|
||||||
accumulated_weight += DEMO_WEIGHT_GRAVITY;
|
// DEMO LITE: Solo física/figuras
|
||||||
if (random_value < accumulated_weight) {
|
TOTAL_WEIGHT = DEMO_LITE_WEIGHT_GRAVITY_DIR + DEMO_LITE_WEIGHT_GRAVITY_TOGGLE
|
||||||
|
+ DEMO_LITE_WEIGHT_SHAPE + DEMO_LITE_WEIGHT_TOGGLE_PHYSICS
|
||||||
|
+ DEMO_LITE_WEIGHT_IMPULSE;
|
||||||
|
random_value = rand() % TOTAL_WEIGHT;
|
||||||
|
|
||||||
|
// Cambiar dirección gravedad (25%)
|
||||||
|
accumulated_weight += DEMO_LITE_WEIGHT_GRAVITY_DIR;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||||
|
changeGravityDirection(new_direction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle gravedad ON/OFF (20%)
|
||||||
|
accumulated_weight += DEMO_LITE_WEIGHT_GRAVITY_TOGGLE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
toggleGravityOnOff();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activar figura 3D (25%)
|
||||||
|
accumulated_weight += DEMO_LITE_WEIGHT_SHAPE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::WAVE_GRID, ShapeType::HELIX,
|
||||||
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
||||||
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||||
|
int shape_index = rand() % 8;
|
||||||
|
activateShape(shapes[shape_index]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle física ↔ figura (20%)
|
||||||
|
accumulated_weight += DEMO_LITE_WEIGHT_TOGGLE_PHYSICS;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
toggleShapeMode(false); // NO forzar gravedad al salir
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar impulso (10%)
|
||||||
|
accumulated_weight += DEMO_LITE_WEIGHT_IMPULSE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
pushBallsAwayFromGravity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// DEMO COMPLETO: Todas las acciones
|
||||||
|
TOTAL_WEIGHT = DEMO_WEIGHT_GRAVITY_DIR + DEMO_WEIGHT_GRAVITY_TOGGLE + DEMO_WEIGHT_SHAPE
|
||||||
|
+ DEMO_WEIGHT_TOGGLE_PHYSICS + DEMO_WEIGHT_REGENERATE_SHAPE + DEMO_WEIGHT_THEME
|
||||||
|
+ DEMO_WEIGHT_SCENARIO + DEMO_WEIGHT_IMPULSE + DEMO_WEIGHT_DEPTH_ZOOM
|
||||||
|
+ DEMO_WEIGHT_SHAPE_SCALE + DEMO_WEIGHT_SPRITE;
|
||||||
|
random_value = rand() % TOTAL_WEIGHT;
|
||||||
|
|
||||||
|
// Cambiar dirección gravedad (10%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_GRAVITY_DIR;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||||
|
changeGravityDirection(new_direction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle gravedad ON/OFF (8%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_GRAVITY_TOGGLE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
toggleGravityOnOff();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activar figura 3D (20%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_SHAPE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::WAVE_GRID, ShapeType::HELIX,
|
||||||
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
||||||
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||||
|
int shape_index = rand() % 8;
|
||||||
|
activateShape(shapes[shape_index]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle física ↔ figura (12%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_TOGGLE_PHYSICS;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
toggleShapeMode(false); // NO forzar gravedad al salir
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-generar misma figura (8%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_REGENERATE_SHAPE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE && active_shape_) {
|
||||||
|
generateShape(); // Re-generar sin cambiar tipo
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambiar tema (15%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_THEME;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
ColorTheme new_theme = static_cast<ColorTheme>(rand() % 6);
|
||||||
|
startThemeTransition(new_theme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambiar escenario (10%) - EXCLUIR índices 0, 6, 7 (1, 50K, 100K pelotas)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_SCENARIO;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
// Escenarios válidos: índices 1, 2, 3, 4, 5 (10, 100, 500, 1000, 10000 pelotas)
|
||||||
|
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
||||||
|
scenario_ = valid_scenarios[rand() % 5];
|
||||||
|
initBalls(scenario_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar impulso (10%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_IMPULSE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
pushBallsAwayFromGravity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle profundidad (3%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_DEPTH_ZOOM;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambiar escala de figura (2%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_SHAPE_SCALE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
int scale_action = rand() % 3;
|
||||||
|
if (scale_action == 0) {
|
||||||
|
shape_scale_factor_ += SHAPE_SCALE_STEP;
|
||||||
|
} else if (scale_action == 1) {
|
||||||
|
shape_scale_factor_ -= SHAPE_SCALE_STEP;
|
||||||
|
} else {
|
||||||
|
shape_scale_factor_ = SHAPE_SCALE_DEFAULT;
|
||||||
|
}
|
||||||
|
clampShapeScale();
|
||||||
|
generateShape();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambiar sprite (2%)
|
||||||
|
accumulated_weight += DEMO_WEIGHT_SPRITE;
|
||||||
|
if (random_value < accumulated_weight) {
|
||||||
|
switchTexture();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Randomizar todo al iniciar modo DEMO
|
||||||
|
void Engine::randomizeOnDemoStart(bool is_lite) {
|
||||||
|
if (is_lite) {
|
||||||
|
// DEMO LITE: Solo randomizar física/figura + gravedad
|
||||||
|
// Elegir aleatoriamente entre modo física o figura
|
||||||
|
if (rand() % 2 == 0) {
|
||||||
|
// Modo física
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
toggleShapeMode(false); // Salir a física sin forzar gravedad
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Modo figura: elegir figura aleatoria
|
||||||
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::WAVE_GRID, ShapeType::HELIX,
|
||||||
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
||||||
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||||
|
activateShape(shapes[rand() % 8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Randomizar gravedad: dirección + ON/OFF
|
||||||
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||||
changeGravityDirection(new_direction);
|
changeGravityDirection(new_direction);
|
||||||
return;
|
if (rand() % 2 == 0) {
|
||||||
}
|
toggleGravityOnOff(); // 50% probabilidad de desactivar gravedad
|
||||||
|
|
||||||
// Acción: Activar figura 3D (25%)
|
|
||||||
accumulated_weight += DEMO_WEIGHT_SHAPE;
|
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
// Elegir figura aleatoria (SPHERE a ATOM = 8 figuras)
|
|
||||||
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::WAVE_GRID, ShapeType::HELIX,
|
|
||||||
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
|
||||||
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
|
||||||
int shape_index = rand() % 8;
|
|
||||||
activateShape(shapes[shape_index]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Cambiar tema (20%)
|
|
||||||
accumulated_weight += DEMO_WEIGHT_THEME;
|
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
ColorTheme new_theme = static_cast<ColorTheme>(rand() % 6); // 6 temas disponibles
|
|
||||||
startThemeTransition(new_theme);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Cambiar escenario/número de pelotas (15%)
|
|
||||||
accumulated_weight += DEMO_WEIGHT_SCENARIO;
|
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
scenario_ = rand() % test_.size();
|
|
||||||
initBalls(scenario_);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Aplicar impulso (10%)
|
|
||||||
accumulated_weight += DEMO_WEIGHT_IMPULSE;
|
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
pushBallsAwayFromGravity();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Toggle profundidad (5%)
|
|
||||||
accumulated_weight += DEMO_WEIGHT_DEPTH_ZOOM;
|
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
if (current_mode_ == SimulationMode::SHAPE) {
|
|
||||||
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Cambiar escala de figura (5%)
|
} else {
|
||||||
accumulated_weight += DEMO_WEIGHT_SHAPE_SCALE;
|
// DEMO COMPLETO: Randomizar TODO
|
||||||
if (random_value < accumulated_weight) {
|
|
||||||
if (current_mode_ == SimulationMode::SHAPE) {
|
// 1. Escenario (excluir índices 0, 6, 7)
|
||||||
// Aleatorio: +1, -1, o reset
|
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
||||||
int scale_action = rand() % 3;
|
scenario_ = valid_scenarios[rand() % 5];
|
||||||
if (scale_action == 0) {
|
initBalls(scenario_);
|
||||||
shape_scale_factor_ += SHAPE_SCALE_STEP;
|
|
||||||
} else if (scale_action == 1) {
|
// 2. Tema
|
||||||
shape_scale_factor_ -= SHAPE_SCALE_STEP;
|
ColorTheme new_theme = static_cast<ColorTheme>(rand() % 6);
|
||||||
} else {
|
startThemeTransition(new_theme);
|
||||||
shape_scale_factor_ = SHAPE_SCALE_DEFAULT;
|
|
||||||
|
// 3. Sprite
|
||||||
|
if (rand() % 2 == 0) {
|
||||||
|
switchTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Física o Figura
|
||||||
|
if (rand() % 2 == 0) {
|
||||||
|
// Modo física
|
||||||
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
toggleShapeMode(false);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Modo figura: elegir figura aleatoria
|
||||||
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::WAVE_GRID, ShapeType::HELIX,
|
||||||
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
||||||
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
||||||
|
activateShape(shapes[rand() % 8]);
|
||||||
|
|
||||||
|
// 5. Profundidad (solo si estamos en figura)
|
||||||
|
if (rand() % 2 == 0) {
|
||||||
|
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Escala de figura (aleatoria entre 0.5x y 2.0x)
|
||||||
|
shape_scale_factor_ = 0.5f + (rand() % 1500) / 1000.0f;
|
||||||
clampShapeScale();
|
clampShapeScale();
|
||||||
generateShape();
|
generateShape();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acción: Cambiar sprite (5%)
|
// 7. Gravedad: dirección + ON/OFF
|
||||||
accumulated_weight += DEMO_WEIGHT_SPRITE;
|
GravityDirection new_direction = static_cast<GravityDirection>(rand() % 4);
|
||||||
if (random_value < accumulated_weight) {
|
changeGravityDirection(new_direction);
|
||||||
switchTexture();
|
if (rand() % 3 == 0) { // 33% probabilidad de desactivar gravedad
|
||||||
return;
|
toggleGravityOnOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle gravedad ON/OFF para todas las pelotas
|
||||||
|
void Engine::toggleGravityOnOff() {
|
||||||
|
// Alternar entre activar/desactivar gravedad
|
||||||
|
bool first_ball_gravity_enabled = (balls_.empty() || balls_[0]->getGravityForce() > 0.0f);
|
||||||
|
|
||||||
|
if (first_ball_gravity_enabled) {
|
||||||
|
// Desactivar gravedad
|
||||||
|
forceBallsGravityOff();
|
||||||
|
} else {
|
||||||
|
// Activar gravedad
|
||||||
|
forceBallsGravityOn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1372,12 +1585,14 @@ void Engine::switchTexture() {
|
|||||||
// Ajustar posiciones según el cambio de tamaño
|
// Ajustar posiciones según el cambio de tamaño
|
||||||
updateBallSizes(old_size, new_size);
|
updateBallSizes(old_size, new_size);
|
||||||
|
|
||||||
// Mostrar texto informativo
|
// Mostrar texto informativo (solo si NO estamos en modo demo)
|
||||||
std::string texture_name = (current_texture_index_ == 0) ? "NORMAL" : "SMALL";
|
if (!demo_mode_enabled_ && !demo_lite_enabled_) {
|
||||||
text_ = "SPRITE: " + texture_name;
|
std::string texture_name = (current_texture_index_ == 0) ? "NORMAL" : "SMALL";
|
||||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
text_ = "SPRITE: " + texture_name;
|
||||||
show_text_ = true;
|
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||||
text_init_time_ = SDL_GetTicks();
|
show_text_ = true;
|
||||||
|
text_init_time_ = SDL_GetTicks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sistema de Figuras 3D - Alternar entre modo física y última figura (Toggle con tecla F)
|
// Sistema de Figuras 3D - Alternar entre modo física y última figura (Toggle con tecla F)
|
||||||
@@ -1400,12 +1615,14 @@ void Engine::toggleShapeMode(bool force_gravity_on_exit) {
|
|||||||
forceBallsGravityOn();
|
forceBallsGravityOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mostrar texto informativo
|
// Mostrar texto informativo (solo si NO estamos en modo demo)
|
||||||
text_ = "MODO FISICA";
|
if (!demo_mode_enabled_ && !demo_lite_enabled_) {
|
||||||
int text_width = static_cast<int>(text_.length() * 8);
|
text_ = "MODO FISICA";
|
||||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
int text_width = static_cast<int>(text_.length() * 8);
|
||||||
text_init_time_ = SDL_GetTicks();
|
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||||
show_text_ = true;
|
text_init_time_ = SDL_GetTicks();
|
||||||
|
show_text_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1460,8 +1677,8 @@ void Engine::activateShape(ShapeType type) {
|
|||||||
ball->enableRotoBallAttraction(true);
|
ball->enableRotoBallAttraction(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mostrar texto informativo con nombre de figura
|
// Mostrar texto informativo con nombre de figura (solo si NO estamos en modo demo)
|
||||||
if (active_shape_) {
|
if (active_shape_ && !demo_mode_enabled_ && !demo_lite_enabled_) {
|
||||||
text_ = std::string("MODO ") + active_shape_->getName();
|
text_ = std::string("MODO ") + active_shape_->getName();
|
||||||
int text_width = static_cast<int>(text_.length() * 8);
|
int text_width = static_cast<int>(text_.length() * 8);
|
||||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ private:
|
|||||||
bool depth_zoom_enabled_ = true; // Zoom por profundidad Z activado
|
bool depth_zoom_enabled_ = true; // Zoom por profundidad Z activado
|
||||||
|
|
||||||
// Sistema de Modo DEMO (auto-play)
|
// Sistema de Modo DEMO (auto-play)
|
||||||
bool demo_mode_enabled_ = false; // ¿Está activo el modo demo?
|
bool demo_mode_enabled_ = false; // ¿Está activo el modo demo completo?
|
||||||
|
bool demo_lite_enabled_ = false; // ¿Está activo el modo demo lite?
|
||||||
float demo_timer_ = 0.0f; // Contador de tiempo para próxima acción
|
float demo_timer_ = 0.0f; // Contador de tiempo para próxima acción
|
||||||
float demo_next_action_time_ = 0.0f; // Tiempo aleatorio hasta próxima acción (segundos)
|
float demo_next_action_time_ = 0.0f; // Tiempo aleatorio hasta próxima acción (segundos)
|
||||||
|
|
||||||
@@ -128,7 +129,9 @@ private:
|
|||||||
|
|
||||||
// Sistema de Modo DEMO
|
// Sistema de Modo DEMO
|
||||||
void updateDemoMode();
|
void updateDemoMode();
|
||||||
void performDemoAction();
|
void performDemoAction(bool is_lite);
|
||||||
|
void randomizeOnDemoStart(bool is_lite);
|
||||||
|
void toggleGravityOnOff();
|
||||||
|
|
||||||
// Sistema de transiciones LERP
|
// Sistema de transiciones LERP
|
||||||
float lerp(float a, float b, float t) const { return a + (b - a) * t; }
|
float lerp(float a, float b, float t) const { return a + (b - a) * t; }
|
||||||
|
|||||||
Reference in New Issue
Block a user