Migración de dbgtxt a SDL_TTF + conversión de textos a mixed case
Sistema de texto: - Reemplazado dbgtxt.cpp (bitmap 8x8) por TextRenderer (SDL_TTF) - Creado source/text/ con TextRenderer class - Añadidas fuentes TrueType en data/fonts/ - Implementados dos TextRenderer (display + debug) con escalado dinámico - Constantes configurables: TEXT_FONT_PATH, TEXT_BASE_SIZE, TEXT_ANTIALIASING Correcciones de centrado: - Reemplazado text.length() * 8 por text_renderer_.getTextWidth() en ~25 lugares - Texto de tecla F ahora se centra correctamente - Texto de modo (Demo/Logo/Lite) fijo en tercera fila del HUD debug - Implementado espaciado dinámico con getTextHeight() Conversión a mixed case: - ~26 textos de display cambiados de ALL CAPS a mixed case - 15 nombres de temas en theme_manager.cpp convertidos a mixed case - Ejemplos: "FPS" → "fps", "MODO FISICA" → "Modo Física", "DEMO MODE ON" → "Modo Demo: On" - Temas: "SUNSET" → "Sunset", "OCEANO" → "Océano", etc. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+14
-6
@@ -16,8 +16,16 @@ if (NOT SDL3_FOUND)
|
||||
message(FATAL_ERROR "SDL3 no encontrado. Por favor, verifica su instalación.")
|
||||
endif()
|
||||
|
||||
# Buscar SDL3_ttf
|
||||
find_package(SDL3_ttf REQUIRED)
|
||||
|
||||
# Si no se encuentra SDL3_ttf, generar un error
|
||||
if (NOT SDL3_ttf_FOUND)
|
||||
message(FATAL_ERROR "SDL3_ttf no encontrado. Por favor, verifica su instalación.")
|
||||
endif()
|
||||
|
||||
# Archivos fuente (excluir main_old.cpp)
|
||||
file(GLOB SOURCE_FILES source/*.cpp source/external/*.cpp source/shapes/*.cpp source/themes/*.cpp)
|
||||
file(GLOB SOURCE_FILES source/*.cpp source/external/*.cpp source/shapes/*.cpp source/themes/*.cpp source/text/*.cpp)
|
||||
list(REMOVE_ITEM SOURCE_FILES "${CMAKE_SOURCE_DIR}/source/main_old.cpp")
|
||||
|
||||
# Comprobar si se encontraron archivos fuente
|
||||
@@ -28,17 +36,17 @@ endif()
|
||||
# Detectar la plataforma y configuraciones específicas
|
||||
if(WIN32)
|
||||
set(PLATFORM windows)
|
||||
set(LINK_LIBS ${SDL3_LIBRARIES} mingw32 ws2_32)
|
||||
set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf mingw32 ws2_32)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
set(PLATFORM linux)
|
||||
set(LINK_LIBS ${SDL3_LIBRARIES})
|
||||
set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf)
|
||||
elseif(APPLE)
|
||||
set(PLATFORM macos)
|
||||
set(LINK_LIBS ${SDL3_LIBRARIES})
|
||||
set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf)
|
||||
endif()
|
||||
|
||||
# Incluir directorios de SDL3
|
||||
include_directories(${SDL3_INCLUDE_DIRS})
|
||||
# Incluir directorios de SDL3 y SDL3_ttf
|
||||
include_directories(${SDL3_INCLUDE_DIRS} ${SDL3_ttf_INCLUDE_DIRS})
|
||||
|
||||
# Añadir el ejecutable reutilizando el nombre del proyecto
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+115
-79
@@ -22,7 +22,6 @@
|
||||
#endif
|
||||
|
||||
#include "ball.h" // for Ball
|
||||
#include "external/dbgtxt.h" // for dbg_init, dbg_print
|
||||
#include "external/mouse.h" // for Mouse namespace
|
||||
#include "external/texture.h" // for Texture
|
||||
#include "shapes/atom_shape.h" // for AtomShape
|
||||
@@ -203,7 +202,22 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) {
|
||||
current_ball_size_ = texture_->getWidth(); // Obtener tamaño dinámicamente
|
||||
|
||||
srand(static_cast<unsigned>(time(nullptr)));
|
||||
dbg_init(renderer_);
|
||||
|
||||
// Calcular tamaño de fuente escalado según resolución
|
||||
// Usa las constantes configurables de la clase
|
||||
int font_size = (base_screen_height_ * TEXT_BASE_SIZE) / 240;
|
||||
|
||||
// Inicializar TextRenderer para display (texto centrado)
|
||||
if (!text_renderer_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING)) {
|
||||
SDL_Log("Error al inicializar TextRenderer (display)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inicializar TextRenderer para debug (HUD)
|
||||
if (!text_renderer_debug_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING)) {
|
||||
SDL_Log("Error al inicializar TextRenderer (debug)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inicializar ThemeManager
|
||||
theme_manager_ = std::make_unique<ThemeManager>();
|
||||
@@ -270,7 +284,7 @@ void Engine::update() {
|
||||
fps_current_ = fps_frame_count_;
|
||||
fps_frame_count_ = 0;
|
||||
fps_last_time_ = current_time;
|
||||
fps_text_ = "FPS: " + std::to_string(fps_current_);
|
||||
fps_text_ = "fps: " + std::to_string(fps_current_);
|
||||
}
|
||||
|
||||
// Bifurcar actualización según modo activo
|
||||
@@ -435,7 +449,7 @@ void Engine::handleEvents() {
|
||||
// Mostrar nombre del tema (solo si NO estamos en modo demo)
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -450,7 +464,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(theme_index);
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -464,7 +478,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(theme_index);
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -478,7 +492,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(theme_index);
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -492,7 +506,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(theme_index);
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -506,7 +520,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(theme_index);
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -519,7 +533,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(5); // MONOCHROME
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -532,7 +546,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(6); // LAVENDER
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -545,7 +559,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(7); // CRIMSON
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -558,7 +572,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(8); // EMERALD
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -571,7 +585,7 @@ void Engine::handleEvents() {
|
||||
theme_manager_->switchToTheme(9); // SUNRISE
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = theme_manager_->getCurrentThemeNameES();
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -585,8 +599,8 @@ void Engine::handleEvents() {
|
||||
|
||||
// Mostrar feedback visual (solo si NO estamos en modo demo)
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = (theme_page_ == 0) ? "PAGINA 1" : "PAGINA 2";
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = (theme_page_ == 0) ? "Página 1" : "Página 2";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -602,7 +616,7 @@ void Engine::handleEvents() {
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ += SHAPE_SCALE_STEP;
|
||||
clampShapeScale();
|
||||
text_ = "SCALE " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
text_ = "Escala " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
@@ -614,7 +628,7 @@ void Engine::handleEvents() {
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ -= SHAPE_SCALE_STEP;
|
||||
clampShapeScale();
|
||||
text_ = "SCALE " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
text_ = "Escala " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
@@ -625,7 +639,7 @@ void Engine::handleEvents() {
|
||||
case SDLK_KP_MULTIPLY:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ = SHAPE_SCALE_DEFAULT;
|
||||
text_ = "SCALE RESET (100%)";
|
||||
text_ = "Escala reiniciada (100%)";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
@@ -636,7 +650,7 @@ void Engine::handleEvents() {
|
||||
case SDLK_KP_DIVIDE:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
||||
text_ = depth_zoom_enabled_ ? "DEPTH ZOOM ON" : "DEPTH ZOOM OFF";
|
||||
text_ = depth_zoom_enabled_ ? "Zoom profundidad: On" : "Zoom profundidad: Off";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
@@ -722,16 +736,16 @@ void Engine::handleEvents() {
|
||||
if (current_app_mode_ == AppMode::DEMO) {
|
||||
// Desactivar DEMO → MANUAL
|
||||
setState(AppMode::MANUAL);
|
||||
text_ = "DEMO MODE OFF";
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = "Modo Demo: Off";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
} else {
|
||||
// Activar DEMO (desde cualquier otro modo)
|
||||
setState(AppMode::DEMO);
|
||||
randomizeOnDemoStart(false);
|
||||
text_ = "DEMO MODE ON";
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = "Modo Demo: On";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -743,16 +757,16 @@ void Engine::handleEvents() {
|
||||
if (current_app_mode_ == AppMode::DEMO_LITE) {
|
||||
// Desactivar DEMO_LITE → MANUAL
|
||||
setState(AppMode::MANUAL);
|
||||
text_ = "DEMO LITE OFF";
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = "Modo Demo Lite: Off";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
} else {
|
||||
// Activar DEMO_LITE (desde cualquier otro modo)
|
||||
setState(AppMode::DEMO_LITE);
|
||||
randomizeOnDemoStart(true);
|
||||
text_ = "DEMO LITE ON";
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = "Modo Demo Lite: On";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -763,11 +777,11 @@ void Engine::handleEvents() {
|
||||
toggleLogoMode();
|
||||
// Mostrar texto informativo
|
||||
if (current_app_mode_ == AppMode::LOGO) {
|
||||
text_ = "LOGO MODE ON";
|
||||
text_ = "Modo Logo: On";
|
||||
} else {
|
||||
text_ = "LOGO MODE OFF";
|
||||
text_ = "Modo Logo: Off";
|
||||
}
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
break;
|
||||
@@ -875,91 +889,115 @@ void Engine::render() {
|
||||
theme_manager_->getCurrentThemeTextColor(text_color_r, text_color_g, text_color_b);
|
||||
const char* theme_name_es = theme_manager_->getCurrentThemeNameES();
|
||||
|
||||
// Calcular espaciado dinámico
|
||||
int line_height = text_renderer_.getTextHeight();
|
||||
int margin = 8;
|
||||
|
||||
// Texto del número de pelotas con color del tema
|
||||
dbg_print(text_pos_, 8, text_.c_str(), text_color_r, text_color_g, text_color_b);
|
||||
text_renderer_.print(text_pos_, margin, text_.c_str(), text_color_r, text_color_g, text_color_b);
|
||||
|
||||
// Mostrar nombre del tema en castellano debajo del número de pelotas
|
||||
// (solo si text_ NO es ya el nombre del tema, para evitar duplicación)
|
||||
if (theme_name_es != nullptr && text_ != theme_name_es) {
|
||||
int theme_text_width = static_cast<int>(strlen(theme_name_es) * 8); // 8 píxeles por carácter
|
||||
int theme_x = (current_screen_width_ - theme_text_width) / 2; // Centrar horizontalmente
|
||||
int theme_text_width = text_renderer_.getTextWidth(theme_name_es);
|
||||
int theme_x = (current_screen_width_ - theme_text_width) / 2; // Centrar horizontalmente
|
||||
int theme_y = margin + line_height; // Espaciado dinámico
|
||||
|
||||
// Texto del nombre del tema con el mismo color
|
||||
dbg_print(theme_x, 24, theme_name_es, text_color_r, text_color_g, text_color_b);
|
||||
text_renderer_.print(theme_x, theme_y, theme_name_es, text_color_r, text_color_g, text_color_b);
|
||||
}
|
||||
}
|
||||
|
||||
// Debug display (solo si está activado con tecla H)
|
||||
if (show_debug_) {
|
||||
// Obtener altura de línea para espaciado dinámico (usando fuente debug)
|
||||
int line_height = text_renderer_debug_.getTextHeight();
|
||||
int margin = 8; // Margen constante
|
||||
int current_y = margin; // Y inicial
|
||||
|
||||
// Mostrar contador de FPS en esquina superior derecha
|
||||
int fps_text_width = static_cast<int>(fps_text_.length() * 8); // 8 píxeles por carácter
|
||||
int fps_x = current_screen_width_ - fps_text_width - 8; // 8 píxeles de margen
|
||||
dbg_print(fps_x, 8, fps_text_.c_str(), 255, 255, 0); // Amarillo para distinguir
|
||||
int fps_text_width = text_renderer_debug_.getTextWidth(fps_text_.c_str());
|
||||
int fps_x = current_screen_width_ - fps_text_width - margin;
|
||||
text_renderer_debug_.print(fps_x, current_y, fps_text_.c_str(), 255, 255, 0); // Amarillo
|
||||
|
||||
// Mostrar estado V-Sync en esquina superior izquierda
|
||||
dbg_print(8, 8, vsync_text_.c_str(), 0, 255, 255); // Cian para distinguir
|
||||
text_renderer_debug_.print(margin, current_y, vsync_text_.c_str(), 0, 255, 255); // Cian
|
||||
current_y += line_height;
|
||||
|
||||
// Debug: Mostrar valores de la primera pelota (si existe)
|
||||
if (!balls_.empty()) {
|
||||
// Línea 1: Gravedad (solo números enteros)
|
||||
// Línea 1: Gravedad
|
||||
int grav_int = static_cast<int>(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
|
||||
std::string grav_text = "Gravedad: " + std::to_string(grav_int);
|
||||
text_renderer_debug_.print(margin, current_y, grav_text.c_str(), 255, 0, 255); // Magenta
|
||||
current_y += line_height;
|
||||
|
||||
// Línea 2: Velocidad Y (solo números enteros)
|
||||
// Línea 2: Velocidad Y
|
||||
int vy_int = static_cast<int>(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
|
||||
std::string vy_text = "Velocidad Y: " + std::to_string(vy_int);
|
||||
text_renderer_debug_.print(margin, current_y, vy_text.c_str(), 255, 0, 255); // Magenta
|
||||
current_y += line_height;
|
||||
|
||||
// Línea 3: Estado superficie
|
||||
std::string surface_text = balls_[0]->isOnSurface() ? "SURFACE YES" : "SURFACE NO";
|
||||
dbg_print(8, 40, surface_text.c_str(), 255, 0, 255); // Magenta para debug
|
||||
std::string surface_text = balls_[0]->isOnSurface() ? "Superficie: Sí" : "Superficie: No";
|
||||
text_renderer_debug_.print(margin, current_y, surface_text.c_str(), 255, 0, 255); // Magenta
|
||||
current_y += line_height;
|
||||
|
||||
// Línea 4: Coeficiente de rebote (loss)
|
||||
float loss_val = balls_[0]->getLossCoefficient();
|
||||
std::string loss_text = "LOSS " + std::to_string(loss_val).substr(0, 4); // Solo 2 decimales
|
||||
dbg_print(8, 48, loss_text.c_str(), 255, 0, 255); // Magenta para debug
|
||||
std::string loss_text = "Rebote: " + std::to_string(loss_val).substr(0, 4);
|
||||
text_renderer_debug_.print(margin, current_y, loss_text.c_str(), 255, 0, 255); // Magenta
|
||||
current_y += line_height;
|
||||
|
||||
// Línea 5: Dirección de gravedad
|
||||
std::string gravity_dir_text = "GRAVITY " + gravityDirectionToString(current_gravity_);
|
||||
dbg_print(8, 56, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo para dirección
|
||||
std::string gravity_dir_text = "Dirección: " + gravityDirectionToString(current_gravity_);
|
||||
text_renderer_debug_.print(margin, current_y, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo
|
||||
current_y += line_height;
|
||||
}
|
||||
|
||||
// Debug: Mostrar tema actual (delegado a ThemeManager)
|
||||
std::string theme_text = std::string("THEME ") + theme_manager_->getCurrentThemeNameEN();
|
||||
dbg_print(8, 64, theme_text.c_str(), 255, 255, 128); // Amarillo claro para tema
|
||||
std::string theme_text = std::string("Tema: ") + theme_manager_->getCurrentThemeNameEN();
|
||||
text_renderer_debug_.print(margin, current_y, theme_text.c_str(), 255, 255, 128); // Amarillo claro
|
||||
current_y += line_height;
|
||||
|
||||
// Debug: Mostrar modo de simulación actual
|
||||
std::string mode_text;
|
||||
if (current_mode_ == SimulationMode::PHYSICS) {
|
||||
mode_text = "MODE PHYSICS";
|
||||
mode_text = "Modo: Física";
|
||||
} else if (active_shape_) {
|
||||
mode_text = std::string("MODE ") + active_shape_->getName();
|
||||
mode_text = std::string("Modo: ") + active_shape_->getName();
|
||||
} else {
|
||||
mode_text = "MODE SHAPE";
|
||||
mode_text = "Modo: Forma";
|
||||
}
|
||||
dbg_print(8, 72, mode_text.c_str(), 0, 255, 128); // Verde claro para modo
|
||||
text_renderer_debug_.print(margin, current_y, mode_text.c_str(), 0, 255, 128); // Verde claro
|
||||
current_y += line_height;
|
||||
|
||||
// Debug: Mostrar convergencia en modo LOGO (solo cuando está activo)
|
||||
if (current_app_mode_ == AppMode::LOGO && current_mode_ == SimulationMode::SHAPE) {
|
||||
int convergence_percent = static_cast<int>(shape_convergence_ * 100.0f);
|
||||
std::string convergence_text = "CONV " + std::to_string(convergence_percent);
|
||||
dbg_print(8, 80, convergence_text.c_str(), 255, 128, 0); // Naranja para convergencia
|
||||
std::string convergence_text = "Convergencia: " + std::to_string(convergence_percent) + "%";
|
||||
text_renderer_debug_.print(margin, current_y, convergence_text.c_str(), 255, 128, 0); // Naranja
|
||||
current_y += line_height;
|
||||
}
|
||||
|
||||
// Debug: Mostrar modo DEMO/LOGO activo (siempre visible cuando debug está ON)
|
||||
// FIJO en tercera fila (no se mueve con otros elementos del HUD)
|
||||
int fixed_y = margin + (line_height * 2); // Tercera fila fija
|
||||
if (current_app_mode_ == AppMode::LOGO) {
|
||||
int logo_text_width = 9 * 8; // "LOGO MODE" = 9 caracteres × 8 píxeles
|
||||
const char* logo_text = "Modo Logo";
|
||||
int logo_text_width = text_renderer_debug_.getTextWidth(logo_text);
|
||||
int logo_x = (current_screen_width_ - logo_text_width) / 2;
|
||||
dbg_print(logo_x, 80, "LOGO MODE", 255, 128, 0); // Naranja para Logo Mode
|
||||
text_renderer_debug_.print(logo_x, fixed_y, logo_text, 255, 128, 0); // Naranja
|
||||
} else if (current_app_mode_ == AppMode::DEMO) {
|
||||
int demo_text_width = 9 * 8; // "DEMO MODE" = 9 caracteres × 8 píxeles
|
||||
const char* demo_text = "Modo Demo";
|
||||
int demo_text_width = text_renderer_debug_.getTextWidth(demo_text);
|
||||
int demo_x = (current_screen_width_ - demo_text_width) / 2;
|
||||
dbg_print(demo_x, 80, "DEMO MODE", 255, 165, 0); // Naranja para DEMO
|
||||
text_renderer_debug_.print(demo_x, fixed_y, demo_text, 255, 165, 0); // Naranja
|
||||
} else if (current_app_mode_ == AppMode::DEMO_LITE) {
|
||||
int lite_text_width = 14 * 8; // "DEMO LITE MODE" = 14 caracteres × 8 píxeles
|
||||
const char* lite_text = "Modo Demo Lite";
|
||||
int lite_text_width = text_renderer_debug_.getTextWidth(lite_text);
|
||||
int lite_x = (current_screen_width_ - lite_text_width) / 2;
|
||||
dbg_print(lite_x, 80, "DEMO LITE MODE", 255, 200, 0); // Amarillo-naranja para DEMO LITE
|
||||
text_renderer_debug_.print(lite_x, fixed_y, lite_text, 255, 200, 0); // Amarillo-naranja
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,11 +1044,11 @@ void Engine::setText() {
|
||||
|
||||
int num_balls = BALL_COUNT_SCENARIOS[scenario_];
|
||||
if (num_balls == 1) {
|
||||
text_ = "1 PELOTA";
|
||||
text_ = "1 pelota";
|
||||
} else {
|
||||
text_ = std::to_string(num_balls) + " PELOTAS";
|
||||
text_ = std::to_string(num_balls) + " pelotas";
|
||||
}
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2; // Centrar texto
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2; // Centrar texto
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -1093,7 +1131,7 @@ void Engine::changeGravityDirection(GravityDirection direction) {
|
||||
|
||||
void Engine::toggleVSync() {
|
||||
vsync_enabled_ = !vsync_enabled_;
|
||||
vsync_text_ = vsync_enabled_ ? "VSYNC ON" : "VSYNC OFF";
|
||||
vsync_text_ = vsync_enabled_ ? "V-Sync: On" : "V-Sync: Off";
|
||||
|
||||
// Aplicar el cambio de V-Sync al renderizador
|
||||
SDL_SetRenderVSync(renderer_, vsync_enabled_ ? 1 : 0);
|
||||
@@ -1199,9 +1237,9 @@ void Engine::toggleIntegerScaling() {
|
||||
SDL_SetRenderLogicalPresentation(renderer_, current_screen_width_, current_screen_height_, presentation);
|
||||
|
||||
// Mostrar texto informativo
|
||||
text_ = "SCALING: ";
|
||||
text_ = "Escalado: ";
|
||||
text_ += mode_name;
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -2021,8 +2059,8 @@ void Engine::switchTexture() {
|
||||
std::string texture_name = texture_names_[current_texture_index_];
|
||||
std::transform(texture_name.begin(), texture_name.end(), texture_name.begin(), ::toupper);
|
||||
|
||||
text_ = "SPRITE: " + texture_name;
|
||||
text_pos_ = (current_screen_width_ - static_cast<int>(text_.length() * 8)) / 2;
|
||||
text_ = "Sprite: " + texture_name;
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
show_text_ = true;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
}
|
||||
@@ -2067,9 +2105,8 @@ void Engine::toggleShapeMode(bool force_gravity_on_exit) {
|
||||
|
||||
// Mostrar texto informativo (solo si NO estamos en modo demo o logo)
|
||||
if (current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = "MODO FISICA";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_ = "Modo Física";
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
show_text_ = true;
|
||||
}
|
||||
@@ -2132,9 +2169,8 @@ void Engine::activateShape(ShapeType type) {
|
||||
|
||||
// Mostrar texto informativo con nombre de figura (solo si NO estamos en modo demo o logo)
|
||||
if (active_shape_ && current_app_mode_ == AppMode::MANUAL) {
|
||||
text_ = std::string("MODO ") + active_shape_->getName();
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_ = std::string("Modo ") + active_shape_->getName();
|
||||
text_pos_ = (current_screen_width_ - text_renderer_.getTextWidth(text_.c_str())) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
show_text_ = true;
|
||||
}
|
||||
|
||||
+33
-25
@@ -10,18 +10,19 @@
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ball.h" // for Ball
|
||||
#include "defines.h" // for GravityDirection, ColorTheme, ShapeType
|
||||
#include "external/texture.h" // for Texture
|
||||
#include "shapes/shape.h" // for Shape (interfaz polimórfica)
|
||||
#include "theme_manager.h" // for ThemeManager
|
||||
#include "ball.h" // for Ball
|
||||
#include "defines.h" // for GravityDirection, ColorTheme, ShapeType
|
||||
#include "external/texture.h" // for Texture
|
||||
#include "shapes/shape.h" // for Shape (interfaz polimórfica)
|
||||
#include "text/textrenderer.h" // for TextRenderer
|
||||
#include "theme_manager.h" // for ThemeManager
|
||||
|
||||
// Modos de aplicación mutuamente excluyentes
|
||||
enum class AppMode {
|
||||
MANUAL, // Control manual del usuario
|
||||
DEMO, // Modo demo completo (auto-play)
|
||||
DEMO_LITE, // Modo demo lite (solo física/figuras)
|
||||
LOGO // Modo logo (easter egg)
|
||||
MANUAL, // Control manual del usuario
|
||||
DEMO, // Modo demo completo (auto-play)
|
||||
DEMO_LITE, // Modo demo lite (solo física/figuras)
|
||||
LOGO // Modo logo (easter egg)
|
||||
};
|
||||
|
||||
class Engine {
|
||||
@@ -54,6 +55,8 @@ class Engine {
|
||||
// UI y debug
|
||||
bool show_debug_ = false;
|
||||
bool show_text_ = true;
|
||||
TextRenderer text_renderer_; // Sistema de renderizado de texto para display (centrado)
|
||||
TextRenderer text_renderer_debug_; // Sistema de renderizado de texto para debug (HUD)
|
||||
|
||||
// Sistema de zoom dinámico
|
||||
int current_window_zoom_ = DEFAULT_WINDOW_ZOOM;
|
||||
@@ -93,22 +96,22 @@ class Engine {
|
||||
bool depth_zoom_enabled_ = true; // Zoom por profundidad Z activado
|
||||
|
||||
// Sistema de Modo DEMO (auto-play)
|
||||
AppMode current_app_mode_ = AppMode::MANUAL; // Modo actual (mutuamente excluyente)
|
||||
AppMode previous_app_mode_ = AppMode::MANUAL; // Modo previo antes de entrar a LOGO
|
||||
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)
|
||||
AppMode current_app_mode_ = AppMode::MANUAL; // Modo actual (mutuamente excluyente)
|
||||
AppMode previous_app_mode_ = AppMode::MANUAL; // Modo previo antes de entrar a LOGO
|
||||
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)
|
||||
|
||||
// Sistema de convergencia para LOGO MODE (escala con resolución)
|
||||
float shape_convergence_ = 0.0f; // % de pelotas cerca del objetivo (0.0-1.0)
|
||||
float logo_convergence_threshold_ = 0.90f; // Threshold aleatorio (75-100%)
|
||||
float logo_min_time_ = 3.0f; // Tiempo mínimo escalado con resolución
|
||||
float logo_max_time_ = 5.0f; // Tiempo máximo escalado (backup)
|
||||
float shape_convergence_ = 0.0f; // % de pelotas cerca del objetivo (0.0-1.0)
|
||||
float logo_convergence_threshold_ = 0.90f; // Threshold aleatorio (75-100%)
|
||||
float logo_min_time_ = 3.0f; // Tiempo mínimo escalado con resolución
|
||||
float logo_max_time_ = 5.0f; // Tiempo máximo escalado (backup)
|
||||
|
||||
// Sistema de espera de flips en LOGO MODE (camino alternativo)
|
||||
bool logo_waiting_for_flip_ = false; // true si eligió el camino "esperar flip"
|
||||
int logo_target_flip_number_ = 0; // En qué flip actuar (1, 2 o 3)
|
||||
float logo_target_flip_percentage_ = 0.0f; // % de flip a esperar (0.2-0.8)
|
||||
int logo_current_flip_count_ = 0; // Flips observados hasta ahora
|
||||
bool logo_waiting_for_flip_ = false; // true si eligió el camino "esperar flip"
|
||||
int logo_target_flip_number_ = 0; // En qué flip actuar (1, 2 o 3)
|
||||
float logo_target_flip_percentage_ = 0.0f; // % de flip a esperar (0.2-0.8)
|
||||
int logo_current_flip_count_ = 0; // Flips observados hasta ahora
|
||||
|
||||
// Estado previo antes de entrar a Logo Mode (para restaurar al salir)
|
||||
int logo_previous_theme_ = 0; // Índice de tema (0-9)
|
||||
@@ -119,6 +122,11 @@ class Engine {
|
||||
std::vector<SDL_Vertex> batch_vertices_;
|
||||
std::vector<int> batch_indices_;
|
||||
|
||||
// Configuración del sistema de texto (constantes configurables)
|
||||
static constexpr const char* TEXT_FONT_PATH = "data/fonts/determination.ttf";
|
||||
static constexpr int TEXT_BASE_SIZE = 8; // Tamaño base para 240p
|
||||
static constexpr bool TEXT_ANTIALIASING = true; // true = suavizado, false = píxeles nítidos
|
||||
|
||||
// Métodos principales del loop
|
||||
void calculateDeltaTime();
|
||||
void update();
|
||||
@@ -141,7 +149,7 @@ class Engine {
|
||||
std::string gravityDirectionToString(GravityDirection direction) const;
|
||||
|
||||
// Sistema de gestión de estados (MANUAL/DEMO/DEMO_LITE/LOGO)
|
||||
void setState(AppMode new_mode); // Cambiar modo de aplicación (mutuamente excluyente)
|
||||
void setState(AppMode new_mode); // Cambiar modo de aplicación (mutuamente excluyente)
|
||||
|
||||
// Sistema de Modo DEMO
|
||||
void updateDemoMode();
|
||||
@@ -150,9 +158,9 @@ class Engine {
|
||||
void toggleGravityOnOff();
|
||||
|
||||
// Sistema de Modo Logo (easter egg)
|
||||
void toggleLogoMode(); // Activar/desactivar modo logo manual (tecla K)
|
||||
void enterLogoMode(bool from_demo = false); // Entrar al modo logo (manual o automático)
|
||||
void exitLogoMode(bool return_to_demo = false); // Salir del modo logo
|
||||
void toggleLogoMode(); // Activar/desactivar modo logo manual (tecla K)
|
||||
void enterLogoMode(bool from_demo = false); // Entrar al modo logo (manual o automático)
|
||||
void exitLogoMode(bool return_to_demo = false); // Salir del modo logo
|
||||
|
||||
// Sistema de cambio de sprites dinámico
|
||||
void switchTexture(); // Cambia a siguiente textura disponible
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#include "textrenderer.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
|
||||
TextRenderer::TextRenderer() : renderer_(nullptr), font_(nullptr), font_size_(0), use_antialiasing_(true) {
|
||||
}
|
||||
|
||||
TextRenderer::~TextRenderer() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
bool TextRenderer::init(SDL_Renderer* renderer, const char* font_path, int font_size, bool use_antialiasing) {
|
||||
renderer_ = renderer;
|
||||
font_size_ = font_size;
|
||||
use_antialiasing_ = use_antialiasing;
|
||||
|
||||
// Inicializar SDL_ttf si no está inicializado
|
||||
if (!TTF_WasInit()) {
|
||||
if (!TTF_Init()) {
|
||||
SDL_Log("Error al inicializar SDL_ttf: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cargar la fuente
|
||||
font_ = TTF_OpenFont(font_path, font_size);
|
||||
if (font_ == nullptr) {
|
||||
SDL_Log("Error al cargar fuente '%s': %s", font_path, SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextRenderer::cleanup() {
|
||||
if (font_ != nullptr) {
|
||||
TTF_CloseFont(font_);
|
||||
font_ = nullptr;
|
||||
}
|
||||
renderer_ = nullptr;
|
||||
}
|
||||
|
||||
void TextRenderer::print(int x, int y, const char* text, uint8_t r, uint8_t g, uint8_t b) {
|
||||
if (!isInitialized() || text == nullptr || text[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Crear superficie con el texto renderizado
|
||||
SDL_Color color = {r, g, b, 255};
|
||||
SDL_Surface* text_surface = nullptr;
|
||||
|
||||
if (use_antialiasing_) {
|
||||
// Con antialiasing (suave, mejor calidad)
|
||||
text_surface = TTF_RenderText_Blended(font_, text, strlen(text), color);
|
||||
} else {
|
||||
// Sin antialiasing (píxeles nítidos, estilo retro)
|
||||
text_surface = TTF_RenderText_Solid(font_, text, strlen(text), color);
|
||||
}
|
||||
|
||||
if (text_surface == nullptr) {
|
||||
SDL_Log("Error al renderizar texto: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Crear textura desde la superficie
|
||||
SDL_Texture* text_texture = SDL_CreateTextureFromSurface(renderer_, text_surface);
|
||||
|
||||
if (text_texture == nullptr) {
|
||||
SDL_Log("Error al crear textura: %s", SDL_GetError());
|
||||
SDL_DestroySurface(text_surface);
|
||||
return;
|
||||
}
|
||||
|
||||
// Preparar rectángulo de destino
|
||||
SDL_FRect dest_rect;
|
||||
dest_rect.x = static_cast<float>(x);
|
||||
dest_rect.y = static_cast<float>(y);
|
||||
dest_rect.w = static_cast<float>(text_surface->w);
|
||||
dest_rect.h = static_cast<float>(text_surface->h);
|
||||
|
||||
// Renderizar la textura
|
||||
SDL_RenderTexture(renderer_, text_texture, nullptr, &dest_rect);
|
||||
|
||||
// Limpiar recursos
|
||||
SDL_DestroyTexture(text_texture);
|
||||
SDL_DestroySurface(text_surface);
|
||||
}
|
||||
|
||||
void TextRenderer::print(int x, int y, const std::string& text, uint8_t r, uint8_t g, uint8_t b) {
|
||||
print(x, y, text.c_str(), r, g, b);
|
||||
}
|
||||
|
||||
int TextRenderer::getTextWidth(const char* text) {
|
||||
if (!isInitialized() || text == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
if (!TTF_GetStringSize(font_, text, strlen(text), &width, &height)) {
|
||||
return 0;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
int TextRenderer::getTextHeight() {
|
||||
if (!isInitialized()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return TTF_GetFontHeight(font_);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
#include <string>
|
||||
|
||||
class TextRenderer {
|
||||
public:
|
||||
TextRenderer();
|
||||
~TextRenderer();
|
||||
|
||||
// Inicializa el renderizador de texto con una fuente
|
||||
bool init(SDL_Renderer* renderer, const char* font_path, int font_size, bool use_antialiasing = true);
|
||||
|
||||
// Libera recursos
|
||||
void cleanup();
|
||||
|
||||
// Renderiza texto en la posición especificada con color RGB
|
||||
void print(int x, int y, const char* text, uint8_t r, uint8_t g, uint8_t b);
|
||||
void print(int x, int y, const std::string& text, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
// Obtiene el ancho de un texto renderizado
|
||||
int getTextWidth(const char* text);
|
||||
|
||||
// Obtiene la altura de la fuente
|
||||
int getTextHeight();
|
||||
|
||||
// Verifica si está inicializado correctamente
|
||||
bool isInitialized() const { return font_ != nullptr && renderer_ != nullptr; }
|
||||
|
||||
private:
|
||||
SDL_Renderer* renderer_;
|
||||
TTF_Font* font_;
|
||||
int font_size_;
|
||||
bool use_antialiasing_;
|
||||
};
|
||||
+28
-28
@@ -17,8 +17,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 0: SUNSET (Atardecer) - Naranjas, rojos, amarillos, rosas
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"SUNSET",
|
||||
"ATARDECER",
|
||||
"Sunset",
|
||||
"Atardecer",
|
||||
255, 140, 60, // Color texto: naranja cálido
|
||||
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
|
||||
@@ -30,8 +30,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 1: OCEAN (Océano) - Azules, turquesas, blancos
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"OCEAN",
|
||||
"OCEANO",
|
||||
"Ocean",
|
||||
"Océano",
|
||||
80, 200, 255, // Color texto: azul océano
|
||||
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
|
||||
@@ -43,8 +43,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 2: NEON - Cian, magenta, verde lima, amarillo vibrante
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"NEON",
|
||||
"NEON",
|
||||
"Neon",
|
||||
"Neón",
|
||||
255, 60, 255, // Color texto: magenta brillante
|
||||
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
|
||||
@@ -56,8 +56,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 3: FOREST (Bosque) - Verdes, marrones, amarillos otoño
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"FOREST",
|
||||
"BOSQUE",
|
||||
"Forest",
|
||||
"Bosque",
|
||||
100, 255, 100, // Color texto: verde natural
|
||||
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
|
||||
@@ -104,8 +104,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 5: MONOCHROME (Monocromo) - Fondo negro degradado, sprites blancos
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"MONOCHROME",
|
||||
"MONOCROMO",
|
||||
"Monochrome",
|
||||
"Monocromo",
|
||||
200, 200, 200, // Color texto: gris claro
|
||||
20.0f / 255.0f, 20.0f / 255.0f, 20.0f / 255.0f, // Fondo superior: gris muy oscuro
|
||||
0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: negro
|
||||
@@ -117,8 +117,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 6: LAVENDER (Lavanda) - Degradado violeta oscuro → azul medianoche, pelotas amarillo dorado
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"LAVENDER",
|
||||
"LAVANDA",
|
||||
"Lavender",
|
||||
"Lavanda",
|
||||
255, 200, 100, // Color texto: amarillo cálido
|
||||
120.0f / 255.0f, 80.0f / 255.0f, 140.0f / 255.0f, // Fondo superior: violeta oscuro
|
||||
25.0f / 255.0f, 30.0f / 255.0f, 60.0f / 255.0f, // Fondo inferior: azul medianoche
|
||||
@@ -130,8 +130,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 7: CRIMSON (Carmesí) - Fondo negro-rojo oscuro, pelotas rojas uniformes
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"CRIMSON",
|
||||
"CARMESI",
|
||||
"Crimson",
|
||||
"Carmesí",
|
||||
255, 100, 100, // Color texto: rojo claro
|
||||
40.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo superior: rojo muy oscuro
|
||||
0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: negro puro
|
||||
@@ -143,8 +143,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 8: EMERALD (Esmeralda) - Fondo negro-verde oscuro, pelotas verdes uniformes
|
||||
themes_.push_back(std::make_unique<StaticTheme>(
|
||||
"EMERALD",
|
||||
"ESMERALDA",
|
||||
"Emerald",
|
||||
"Esmeralda",
|
||||
100, 255, 100, // Color texto: verde claro
|
||||
0.0f / 255.0f, 40.0f / 255.0f, 0.0f / 255.0f, // Fondo superior: verde muy oscuro
|
||||
0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, // Fondo inferior: negro puro
|
||||
@@ -160,8 +160,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 9: SUNRISE (Amanecer) - Noche → Alba → Día (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"SUNRISE",
|
||||
"AMANECER",
|
||||
"Sunrise",
|
||||
"Amanecer",
|
||||
255, 200, 100, // Color texto: amarillo cálido
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Noche oscura (estado inicial)
|
||||
@@ -201,8 +201,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 10: OCEAN WAVES (Olas Oceánicas) - Azul oscuro ↔ Turquesa (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"OCEAN WAVES",
|
||||
"OLAS OCEANICAS",
|
||||
"Ocean Waves",
|
||||
"Olas Oceánicas",
|
||||
100, 220, 255, // Color texto: cian claro
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Profundidad oceánica (azul oscuro)
|
||||
@@ -232,8 +232,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 11: NEON PULSE (Pulso Neón) - Negro → Neón brillante (rápido ping-pong)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"NEON PULSE",
|
||||
"PULSO NEON",
|
||||
"Neon Pulse",
|
||||
"Pulso Neón",
|
||||
255, 60, 255, // Color texto: magenta brillante
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Apagado (negro)
|
||||
@@ -263,8 +263,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 12: FIRE (Fuego Vivo) - Brasas → Llamas → Inferno (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"FIRE",
|
||||
"FUEGO",
|
||||
"Fire",
|
||||
"Fuego",
|
||||
255, 150, 80, // Color texto: naranja cálido
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Brasas oscuras (estado inicial)
|
||||
@@ -314,8 +314,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 13: AURORA (Aurora Boreal) - Verde → Violeta → Cian (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"AURORA",
|
||||
"AURORA",
|
||||
"Aurora",
|
||||
"Aurora",
|
||||
150, 255, 200, // Color texto: verde claro
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Verde aurora (estado inicial)
|
||||
@@ -365,8 +365,8 @@ void ThemeManager::initialize() {
|
||||
|
||||
// 14: VOLCANIC (Erupción Volcánica) - Ceniza → Erupción → Lava (loop)
|
||||
themes_.push_back(std::make_unique<DynamicTheme>(
|
||||
"VOLCANIC",
|
||||
"VOLCAN",
|
||||
"Volcanic",
|
||||
"Volcán",
|
||||
200, 120, 80, // Color texto: naranja apagado
|
||||
std::vector<DynamicThemeKeyframe>{
|
||||
// Keyframe 0: Ceniza oscura (pre-erupción)
|
||||
|
||||
Reference in New Issue
Block a user