diff --git a/README.md b/README.md index eba4373..cba609f 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ - **Simulacion de fisica**: Gravedad, rebotes y colisiones con perdida de energia - **Multiples escenarios**: 8 configuraciones predefinidas (1 a 100,000 pelotas) +- **Sistema de temas visuales**: 4 temas de colores con fondos degradados y paletas tematicas - **Interactividad**: Controles de teclado para modificar el comportamiento - **Renderizado batch optimizado**: Sistema de batch rendering con SDL_RenderGeometry para 50K+ sprites -- **Colores aleatorios**: Cada pelota tiene un color unico generado proceduralmente +- **Colores tematicos**: Paletas de 8 colores por tema aplicadas proceduralmente - **Monitor de rendimiento**: Contador FPS en tiempo real - **Control V-Sync**: Activacion/desactivacion dinamica del V-Sync @@ -18,6 +19,8 @@ |-------|--------| | `H` | **Alternar debug display (FPS, V-Sync, valores fisica)** | | `V` | **Alternar V-Sync ON/OFF** | +| `F1-F4` | **Seleccion directa de tema de colores (Atardecer/Oceano/Neon/Bosque)** | +| `T` | **Ciclar entre temas de colores** | | `1-8` | Cambiar numero de pelotas (1, 10, 100, 500, 1K, 10K, 50K, 100K) | | `ESPACIO` | Impulsar todas las pelotas hacia arriba | | `G` | Alternar direccion de la gravedad | @@ -26,14 +29,43 @@ ## 📊 Informacion en Pantalla - **Centro**: Numero de pelotas activas en **blanco** (temporal) +- **Centro**: Nombre del tema activo en **color tematico** (temporal, debajo del contador) ### Debug Display (Tecla `H`) Cuando se activa el debug display con la tecla `H`: -- **Esquina superior izquierda**: Estado V-Sync (VSYNC: ON/OFF) en **cian** +- **Esquina superior izquierda**: Estado V-Sync (VSYNC ON/OFF) en **cian** - **Esquina superior derecha**: Contador FPS en tiempo real en **amarillo** -- **Linea 3**: Valores fisica primera pelota (GRAV, VY, FLOOR) en **magenta** +- **Lineas 3-5**: Valores fisica primera pelota (GRAV, VY, FLOOR) en **magenta** +- **Linea 6**: Tema activo (THEME SUNSET/OCEAN/NEON/FOREST) en **amarillo claro** + +## 🎨 Sistema de Temas de Colores + +**ViBe1 Delta** incluye 4 temas visuales que transforman completamente la apariencia del simulador: + +### Temas Disponibles + +| Tecla | Tema | Descripcion | Fondo | Paleta de Pelotas | +|-------|------|-------------|-------|-------------------| +| `F1` | **ATARDECER** | Colores calidos de puesta de sol | Degradado naranja-rojo | Tonos naranjas, rojos y amarillos | +| `F2` | **OCEANO** | Ambiente marino refrescante | Degradado azul-cian | Azules, cianes y verdes agua | +| `F3` | **NEON** | Colores vibrantes futuristas | Degradado magenta-cian | Magentas, cianes y rosas brillantes | +| `F4` | **BOSQUE** | Naturaleza verde relajante | Degradado verde oscuro-claro | Verdes naturales y tierra | + +### Controles de Temas + +- **Seleccion directa**: Usa `F1`, `F2`, `F3` o `F4` para cambiar inmediatamente al tema deseado +- **Ciclado secuencial**: Presiona `T` para avanzar al siguiente tema en orden +- **Indicador visual**: El nombre del tema aparece temporalmente en el centro de la pantalla con colores tematicos +- **Regeneracion automatica**: Las pelotas adoptan automaticamente la nueva paleta de colores al cambiar tema + +### Detalles Tecnicos + +- **Fondos degradados**: Implementados con `SDL_RenderGeometry` usando vertices con colores interpolados +- **Paletas tematicas**: 8 colores unicos por tema aplicados aleatoriamente a las pelotas +- **Rendimiento optimizado**: El cambio de tema solo regenera los colores, manteniendo la fisica +- **Compatibilidad completa**: Funciona con todos los escenarios (1 a 100,000 pelotas) ## 🏗️ Estructura del Proyecto diff --git a/source/main.cpp b/source/main.cpp index 7a4afc5..9d66111 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -41,7 +41,7 @@ std::string fps_text = "FPS: 0"; // Texto del contador de FPS // Variables para V-Sync bool vsync_enabled = true; // Estado inicial del V-Sync (activado por defecto) -std::string vsync_text = "VSYNC: ON"; // Texto del estado V-Sync +std::string vsync_text = "VSYNC ON"; // Texto del estado V-Sync // Variables para Delta Time Uint64 last_frame_time = 0; // Tiempo del último frame en milisegundos @@ -50,10 +50,105 @@ float delta_time = 0.0f; // Tiempo transcurrido desde el último frame en seg // Variables para Debug Display bool show_debug = false; // Debug display desactivado por defecto +// Sistema de temas de colores +enum class ColorTheme { + SUNSET = 0, + OCEAN = 1, + NEON = 2, + FOREST = 3 +}; + +ColorTheme current_theme = ColorTheme::SUNSET; +std::string theme_names[] = {"SUNSET", "OCEAN", "NEON", "FOREST"}; + +struct ThemeColors { + // Colores de fondo (superior -> inferior) + float bg_top_r, bg_top_g, bg_top_b; + float bg_bottom_r, bg_bottom_g, bg_bottom_b; + + // Paletas de colores para bolas (RGB 0-255) + int ball_colors[8][3]; // 8 colores por tema +}; + +ThemeColors themes[4] = { + // SUNSET: Naranjas, rojos, amarillos, rosas + { + 180.0f/255.0f, 140.0f/255.0f, 100.0f/255.0f, // Fondo superior (naranja suave) + 40.0f/255.0f, 20.0f/255.0f, 60.0f/255.0f, // Fondo inferior (púrpura oscuro) + {{255, 140, 0}, {255, 69, 0}, {255, 215, 0}, {255, 20, 147}, // Bolas sunset + {255, 99, 71}, {255, 165, 0}, {255, 192, 203}, {220, 20, 60}} + }, + // OCEAN: Azules, cianes, verdes agua, blancos + { + 100.0f/255.0f, 150.0f/255.0f, 200.0f/255.0f, // Fondo superior (azul cielo) + 20.0f/255.0f, 40.0f/255.0f, 80.0f/255.0f, // Fondo inferior (azul marino) + {{0, 191, 255}, {0, 255, 255}, {32, 178, 170}, {176, 224, 230}, // Bolas ocean + {70, 130, 180}, {0, 206, 209}, {240, 248, 255}, {64, 224, 208}} + }, + // NEON: Cian, magenta, verde lima, amarillo vibrante + { + 20.0f/255.0f, 20.0f/255.0f, 40.0f/255.0f, // Fondo superior (negro azulado) + 0.0f/255.0f, 0.0f/255.0f, 0.0f/255.0f, // Fondo inferior (negro) + {{0, 255, 255}, {255, 0, 255}, {50, 205, 50}, {255, 255, 0}, // Bolas neon + {255, 20, 147}, {0, 255, 127}, {138, 43, 226}, {255, 69, 0}} + }, + // FOREST: Verdes, marrones, amarillos otoño + { + 144.0f/255.0f, 238.0f/255.0f, 144.0f/255.0f, // Fondo superior (verde claro) + 101.0f/255.0f, 67.0f/255.0f, 33.0f/255.0f, // Fondo inferior (marrón tierra) + {{34, 139, 34}, {107, 142, 35}, {154, 205, 50}, {255, 215, 0}, // Bolas forest + {210, 180, 140}, {160, 82, 45}, {218, 165, 32}, {50, 205, 50}} + } +}; + // Variables para Batch Rendering std::vector batch_vertices; std::vector batch_indices; +// Función para renderizar fondo degradado +void renderGradientBackground() +{ + // Crear quad de pantalla completa con degradado + SDL_Vertex bg_vertices[4]; + + // Obtener colores del tema actual + ThemeColors& theme = themes[static_cast(current_theme)]; + + float top_r = theme.bg_top_r; + float top_g = theme.bg_top_g; + float top_b = theme.bg_top_b; + + float bottom_r = theme.bg_bottom_r; + float bottom_g = theme.bg_bottom_g; + float bottom_b = theme.bg_bottom_b; + + // Vértice superior izquierdo + bg_vertices[0].position = {0, 0}; + bg_vertices[0].tex_coord = {0.0f, 0.0f}; + bg_vertices[0].color = {top_r, top_g, top_b, 1.0f}; + + // Vértice superior derecho + bg_vertices[1].position = {SCREEN_WIDTH, 0}; + bg_vertices[1].tex_coord = {1.0f, 0.0f}; + bg_vertices[1].color = {top_r, top_g, top_b, 1.0f}; + + // Vértice inferior derecho + bg_vertices[2].position = {SCREEN_WIDTH, SCREEN_HEIGHT}; + bg_vertices[2].tex_coord = {1.0f, 1.0f}; + bg_vertices[2].color = {bottom_r, bottom_g, bottom_b, 1.0f}; + + // Vértice inferior izquierdo + bg_vertices[3].position = {0, SCREEN_HEIGHT}; + bg_vertices[3].tex_coord = {0.0f, 1.0f}; + bg_vertices[3].color = {bottom_r, bottom_g, bottom_b, 1.0f}; + + // Índices para 2 triángulos + int bg_indices[6] = {0, 1, 2, 2, 3, 0}; + + // Renderizar sin textura (nullptr) + SDL_RenderGeometry(renderer, nullptr, bg_vertices, 4, bg_indices, 6); +} + // Función para añadir un sprite al batch void addSpriteToBatch(float x, float y, float w, float h, Uint8 r, Uint8 g, Uint8 b) { @@ -125,7 +220,12 @@ void initBalls(int value) const float X = (rand() % (SCREEN_WIDTH / 2)) + (SCREEN_WIDTH / 4); // Posición inicial en X const float VX = (((rand() % 20) + 10) * 0.1f) * SIGN; // Velocidad en X const float VY = ((rand() % 60) - 30) * 0.1f; // Velocidad en Y - const Color COLOR = {(rand() % 192) + 32, (rand() % 192) + 32, (rand() % 192) + 32}; // Color aleatorio + // Seleccionar color de la paleta del tema actual + ThemeColors& theme = themes[static_cast(current_theme)]; + int color_index = rand() % 8; // 8 colores por tema + const Color COLOR = {theme.ball_colors[color_index][0], + theme.ball_colors[color_index][1], + theme.ball_colors[color_index][2]}; balls.emplace_back(std::make_unique(X, VX, VY, COLOR, texture)); } setText(); // Actualiza el texto @@ -156,7 +256,7 @@ void switchBallsGravity() void toggleVSync() { vsync_enabled = !vsync_enabled; - vsync_text = vsync_enabled ? "VSYNC: ON" : "VSYNC: OFF"; + vsync_text = vsync_enabled ? "VSYNC ON" : "VSYNC OFF"; // Aplicar el cambio de V-Sync al renderizador SDL_SetRenderVSync(renderer, vsync_enabled ? 1 : 0); @@ -285,6 +385,32 @@ void checkEvents() show_debug = !show_debug; break; + case SDLK_T: + // Ciclar al siguiente tema + current_theme = static_cast((static_cast(current_theme) + 1) % 4); + initBalls(scenario); // Regenerar bolas con nueva paleta + break; + + case SDLK_F1: + current_theme = ColorTheme::SUNSET; + initBalls(scenario); + break; + + case SDLK_F2: + current_theme = ColorTheme::OCEAN; + initBalls(scenario); + break; + + case SDLK_F3: + current_theme = ColorTheme::NEON; + initBalls(scenario); + break; + + case SDLK_F4: + current_theme = ColorTheme::FOREST; + initBalls(scenario); + break; + case SDLK_1: scenario = 0; initBalls(scenario); @@ -359,8 +485,8 @@ void update() // Renderiza el contenido en la pantalla void render() { - SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255); - SDL_RenderClear(renderer); + // Renderizar fondo degradado en lugar de color sólido + renderGradientBackground(); // Limpiar batches del frame anterior batch_vertices.clear(); @@ -386,6 +512,25 @@ void render() if (show_text) { dbg_print(text_pos, 8, text.c_str(), 255, 255, 255); + + // Mostrar nombre del tema en castellano debajo del número de pelotas + std::string theme_names_es[] = {"ATARDECER", "OCEANO", "NEON", "BOSQUE"}; + std::string theme_name = theme_names_es[static_cast(current_theme)]; + int theme_text_width = static_cast(theme_name.length() * 8); // 8 píxeles por carácter + int theme_x = (SCREEN_WIDTH - theme_text_width) / 2; // Centrar horizontalmente + + // Colores acordes a cada tema + int theme_colors[][3] = { + {255, 140, 60}, // ATARDECER: Naranja cálido + {80, 200, 255}, // OCEANO: Azul océano + {255, 60, 255}, // NEON: Magenta brillante + {100, 255, 100} // BOSQUE: Verde natural + }; + int theme_idx = static_cast(current_theme); + dbg_print(theme_x, 24, theme_name.c_str(), + theme_colors[theme_idx][0], + theme_colors[theme_idx][1], + theme_colors[theme_idx][2]); } // Debug display (solo si está activado con tecla H) @@ -402,11 +547,25 @@ void render() // Debug: Mostrar valores de la primera pelota (si existe) if (!balls.empty()) { - std::string debug_text = "GRAV: " + std::to_string(balls[0]->getGravityForce()) + - " VY: " + std::to_string(balls[0]->getVelocityY()) + - " FLOOR: " + (balls[0]->isOnFloor() ? "YES" : "NO"); - dbg_print(8, 24, debug_text.c_str(), 255, 0, 255); // Magenta para debug + // Línea 1: Gravedad (solo números enteros) + int grav_int = static_cast(balls[0]->getGravityForce()); + std::string grav_text = "GRAV " + std::to_string(grav_int); + dbg_print(8, 24, grav_text.c_str(), 255, 0, 255); // Magenta para debug + + // Línea 2: Velocidad Y (solo números enteros) + int vy_int = static_cast(balls[0]->getVelocityY()); + std::string vy_text = "VY " + std::to_string(vy_int); + dbg_print(8, 32, vy_text.c_str(), 255, 0, 255); // Magenta para debug + + // Línea 3: Estado suelo + std::string floor_text = balls[0]->isOnFloor() ? "FLOOR YES" : "FLOOR NO"; + dbg_print(8, 40, floor_text.c_str(), 255, 0, 255); // Magenta para debug } + + // Debug: Mostrar tema actual + std::string theme_names[] = {"SUNSET", "OCEAN", "NEON", "FOREST"}; + std::string theme_text = "THEME " + theme_names[static_cast(current_theme)]; + dbg_print(8, 48, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema } SDL_RenderPresent(renderer);