From c9a29e26dd0e2ca46258e38479332b88c0585c40 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 24 Sep 2025 11:37:23 +0200 Subject: [PATCH] revisant la seccio game: bales, items e inici --- data/gfx/player/player.ani | 6 +- game_cpp_repair_plan.md | 136 +++++++++++++++++++++++++++++++++++++ source/bullet.cpp | 2 +- source/bullet.h | 8 +-- source/director.cpp | 2 +- source/item.h | 8 +-- source/sections/game.cpp | 24 ++++--- 7 files changed, 165 insertions(+), 21 deletions(-) create mode 100644 game_cpp_repair_plan.md diff --git a/data/gfx/player/player.ani b/data/gfx/player/player.ani index 0c63f77..5a2fda4 100644 --- a/data/gfx/player/player.ani +++ b/data/gfx/player/player.ani @@ -10,7 +10,7 @@ frames=0,1,2,3 [animation] name=stand -speed=0.0167 +speed=0.167 loop=0 frames=4,5,6,7 [/animation] @@ -101,14 +101,14 @@ frames=37 [animation] name=rolling -speed=0.0167 +speed=0.167 loop=0 frames=38,39,40,41 [/animation] [animation] name=celebration -speed=0.0167 +speed=0.167 loop=-1 frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42 [/animation] diff --git a/game_cpp_repair_plan.md b/game_cpp_repair_plan.md new file mode 100644 index 0000000..772767c --- /dev/null +++ b/game_cpp_repair_plan.md @@ -0,0 +1,136 @@ +# Plan de Reparación: game.cpp - Limpieza DeltaTime + +## Estado Actual +✅ `calculateDeltaTime()` convertido a segundos +✅ Constantes de tiempo convertidas de `_MS` a `_S` +✅ Eliminados hardcoded `1000.0f / 60.0f` +✅ `throwCoffee()` velocidades convertidas a pixels/segundo +✅ Frame-based counter en `updateGameStateShowingGetReadyMessage()` convertido a timer con flag + +## Problemas Detectados Pendientes + +### ✅ COMPLETADO +1. **Valores hardcoded frame-based (60, 16.67, 1000/60)** - Solo quedan las conversiones correctas +2. **SmartSprite setFinishedDelay() calls** - Correcto (0.0F está bien) +3. **Velocidades y aceleraciones** - Todas convertidas correctamente +4. **Timer variables** - Todas usan deltaTime correctamente + +### ❌ PENDIENTES DE REPARAR + +#### ✅ **SOLUCIONADO: Balas no se mueven** +- **Síntoma**: Las balas se crean pero no avanzan en pantalla +- **Causa encontrada**: Velocidades en `bullet.h` seguían en pixels/ms pero `calculateDeltaTime()` ahora devuelve segundos +- **Solución aplicada**: + - `VEL_Y = -0.18F` → `VEL_Y = -180.0F` (pixels/segundo) + - `VEL_X_LEFT = -0.12F` → `VEL_X_LEFT = -120.0F` (pixels/segundo) + - `VEL_X_RIGHT = 0.12F` → `VEL_X_RIGHT = 120.0F` (pixels/segundo) + - Actualizado comentario en `bullet.cpp`: "pixels/ms" → "pixels/segundo" + +#### ✅ **SOLUCIONADO: Contadores frame-based (++ o -- operations)** +- **Problema**: `demo_.counter++` en líneas 1665, 1691 +- **Ubicación**: `updateDemo()` y `updateRecording()` +- **Contexto**: `demo_.counter` indexa un vector con datos de teclas por frame (ej: 2000 frames = 2000 entradas) +- **Solución aplicada**: Acumulador de tiempo que se incrementa cada 16.67ms (1/60 segundos) +- **Implementación**: + ```cpp + // updateDemo() + static float demo_frame_timer = 0.0f; + demo_frame_timer += calculateDeltaTime(); + if (demo_frame_timer >= 0.01667f && demo_.counter < TOTAL_DEMO_DATA) { + demo_.counter++; + demo_frame_timer -= 0.01667f; // Mantener precisión acumulada + } + + // updateRecording() + static float recording_frame_timer = 0.0f; + recording_frame_timer += calculateDeltaTime(); + if (recording_frame_timer >= 0.01667f && demo_.counter < TOTAL_DEMO_DATA) { + demo_.counter++; + recording_frame_timer -= 0.01667f; // Mantener precisión acumulada + } + ``` + +#### 6. **Fade duration values (milisegundos vs segundos)** +- **Problema 1**: `fade_out_->setPostDuration(500);` línea 234 +- **Problema 2**: `fade_out_->setPostDuration(param.fade.post_duration_ms);` líneas 89, 1671 +- **Solución**: Verificar si `param.fade.post_duration_ms` debe ser convertido a segundos + +### NUEVOS PROBLEMAS A AÑADIR + +#### 7. **Verificar param.fade estructura** +- Revisar si `param.fade.post_duration_ms` debe ser convertido a segundos +- Verificar todas las propiedades de `param.fade` relacionadas con tiempo + +#### 8. **Revisar constantes TOTAL_DEMO_DATA** +- **Problema**: `TOTAL_DEMO_DATA - 200` en línea 1669 +- **Detalle**: 200 frames hardcoded, debería ser tiempo en segundos + +#### 9. **Buscar más magic numbers relacionados con tiempo** +- Buscar números como 100, 150, 200, 500 que puedan ser frames +- Verificar contexto de cada uno + +#### 10. **Revisar setRotateSpeed() values** +- **Problema**: `setRotateSpeed(10)` línea 797 +- **Verificar**: Si debe ser convertido de rotaciones/frame a rotaciones/segundo + +#### ✅ **VERIFICADO: SDL_Delay() calls** +- **Problema**: `SDL_Delay(param.game.hit_stop_ms);` línea 847 +- **Ubicación**: `handlePlayerCollision()` +- **Contexto**: Pausa el juego al recibir daño (hitStop effect) +- **Resultado**: `param.game.hit_stop_ms` está configurado explícitamente en milisegundos en archivos .txt +- **Conclusión**: Correcto, `SDL_Delay()` espera milisegundos y `hit_stop_ms` ya está en milisegundos + +#### ✅ **VERIFICADO: Cooldown de disparos en frames** +- **Problema**: `handleFireInput()` líneas 1312-1314 +- **Detalle**: `POWERUP_COOLDOWN = 5`, `AUTOFIRE_COOLDOWN = 10`, `NORMAL_COOLDOWN = 7` +- **Contexto**: Son frames de cooldown, se pasan a `player->startFiringSystem(cant_fire_counter)` +- **Resultado**: `startFiringSystem()` convierte internamente frames a segundos con: `fire_cooldown_timer_ = static_cast(cooldown_frames) / 60.0f;` +- **Conclusión**: No necesita cambios, la conversión ya está implementada correctamente + +#### 12. **Revisar paths y PathSprite durations** +- **Problema**: En `initPaths()` líneas 1024, 1025, 1036, 1037, 1049, 1050, 1062, 1063 +- **Detalle**: `createPath(..., 80, ...), 20);` - Los números 80 y 20 son frames +- **Ejemplo**: `paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 20);` +- **Investigar**: Si createPath espera segundos o milisegundos +- **Conversión**: 80 frames = 80/60 = 1.33s, 20 frames = 20/60 = 0.33s +- **Verificar**: Documentación de createPath() y PathSprite para unidades correctas + +## Herramientas de Búsqueda Útiles + +```bash +# Buscar magic numbers de tiempo +rg "\b(100|150|200|250|300|400|500|1000)\b" --context=2 + +# Buscar más frame-based operations +rg "setRotateSpeed|SDL_Delay|createPath.*[0-9]+" + +# Buscar estructuras param que mencionen tiempo +rg "param\..*\.(duration|time|delay|ms|frames)" + +# Buscar comentarios con "frame" or "60fps" +rg "(frame|60fps|milliseconds)" --ignore-case +``` + +## Prioridad de Reparación + +### ✅ COMPLETADAS +1. ✅ **CRÍTICA**: Las balas no se desplazan - **SOLUCIONADO**: Velocidades convertidas de pixels/ms a pixels/segundo +2. ✅ **ALTA**: demo_.counter system - **SOLUCIONADO**: Implementados acumuladores de tiempo +3. ✅ **ALTA**: Fade durations hardcoded - **SOLUCIONADO**: Convertidos a segundos +4. ✅ **ALTA**: initPaths() frame values - **SOLUCIONADO**: Convertidos a segundos +5. ✅ **MEDIA**: Cooldown de disparos - **VERIFICADO**: Ya convierte internamente frames a segundos +6. ✅ **BAJA**: SDL_Delay investigation - **VERIFICADO**: Correcto, usa milisegundos + +### ❌ PENDIENTES +7. **MEDIA**: param.fade.post_duration_ms verification (líneas 89, 1671) +8. **MEDIA**: TOTAL_DEMO_DATA - 200 magic number (línea 1669) - Nota: No necesita cambios, lógica correcta +9. **BAJA**: setRotateSpeed verification (línea 797) +10. **BAJA**: Comprehensive magic number search + +## Notas Importantes + +- **TODOS los contadores deben ser crecientes** (0 → constante_tope) +- **SOLO SEGUNDOS** en todo el codebase, NO frames ni milisegundos simultáneos +- **Documentar conversiones** con comentarios explicativos +- **Crear constantes** para valores repetidos +- **Evitar números mágicos** sin contexto \ No newline at end of file diff --git a/source/bullet.cpp b/source/bullet.cpp index 8770a1c..d327a27 100644 --- a/source/bullet.cpp +++ b/source/bullet.cpp @@ -68,7 +68,7 @@ auto Bullet::update(float deltaTime) -> BulletMoveStatus { // Implementación del movimiento usando BulletMoveStatus (time-based) auto Bullet::move(float deltaTime) -> BulletMoveStatus { - // DeltaTime puro: velocidad (pixels/ms) * tiempo (ms) + // DeltaTime puro: velocidad (pixels/segundo) * tiempo (segundos) pos_x_ += vel_x_ * deltaTime; if (pos_x_ < param.game.play_area.rect.x - WIDTH || pos_x_ > param.game.play_area.rect.w) { disable(); diff --git a/source/bullet.h b/source/bullet.h index c5bdc9d..a16b52a 100644 --- a/source/bullet.h +++ b/source/bullet.h @@ -45,10 +45,10 @@ class Bullet { private: // --- Constantes --- - static constexpr float VEL_Y = -0.18F; // Velocidad vertical (pixels/ms) - static constexpr float VEL_X_LEFT = -0.12F; // Velocidad izquierda (pixels/ms) - static constexpr float VEL_X_RIGHT = 0.12F; // Velocidad derecha (pixels/ms) - static constexpr float VEL_X_CENTER = 0.0F; // Velocidad central + static constexpr float VEL_Y = -180.0F; // Velocidad vertical (pixels/segundo) - era -0.18F pixels/ms + static constexpr float VEL_X_LEFT = -120.0F; // Velocidad izquierda (pixels/segundo) - era -0.12F pixels/ms + static constexpr float VEL_X_RIGHT = 120.0F; // Velocidad derecha (pixels/segundo) - era 0.12F pixels/ms + static constexpr float VEL_X_CENTER = 0.0F; // Velocidad central // --- Objetos y punteros --- std::unique_ptr sprite_; // Sprite con los gráficos diff --git a/source/director.cpp b/source/director.cpp index 525f3cf..31055e2 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -42,7 +42,7 @@ Director::Director(int argc, std::span argv) { Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #elif _DEBUG - Section::name = Section::Name::TITLE; + Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #else // NORMAL GAME Section::name = Section::Name::LOGO; diff --git a/source/item.h b/source/item.h index a0a6d2a..4ec2fdf 100644 --- a/source/item.h +++ b/source/item.h @@ -32,15 +32,15 @@ class Item { static constexpr float LIFETIME_DURATION_S = 10.0f; // Duración de vida del ítem en segundos // Velocidades base (pixels/segundo) - Coffee Machine - static constexpr float COFFEE_MACHINE_VEL_X_FACTOR = 1.8F; // Factor para velocidad X de máquina de café (0.03*60) - static constexpr float COFFEE_MACHINE_VEL_Y = -0.36F; // Velocidad Y inicial de máquina de café (-0.006*60) - static constexpr float COFFEE_MACHINE_ACCEL_Y = 1.296F; // Aceleración Y de máquina de café (pixels/segundo²) + static constexpr float COFFEE_MACHINE_VEL_X_FACTOR = 30.0F; // Factor para velocidad X de máquina de café (0.5*60fps) + static constexpr float COFFEE_MACHINE_VEL_Y = -6.0F; // Velocidad Y inicial de máquina de café (-0.1*60fps) + static constexpr float COFFEE_MACHINE_ACCEL_Y = 360.0F; // Aceleración Y de máquina de café (0.1*60²fps = 360 pixels/segundo²) // Velocidades base (pixels/segundo) - Items normales static constexpr float ITEM_VEL_X_BASE = 60.0F; // Velocidad X base para items (1.0F*60fps) static constexpr float ITEM_VEL_X_STEP = 20.0F; // Incremento de velocidad X (0.33F*60fps) static constexpr float ITEM_VEL_Y = -240.0F; // Velocidad Y inicial de items (-4.0F*60fps) - static constexpr float ITEM_ACCEL_Y = 12.0F; // Aceleración Y de items (pixels/segundo²) + static constexpr float ITEM_ACCEL_Y = 720.0F; // Aceleración Y de items (0.2*60²fps = 720 pixels/segundo²) // Constantes de física de rebote static constexpr float BOUNCE_VEL_THRESHOLD = 60.0F; // Umbral de velocidad para parar (1.0F*60fps) diff --git a/source/sections/game.cpp b/source/sections/game.cpp index e0d0fa3..2cc04ab 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -1021,7 +1021,7 @@ void Game::initPaths() { const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = param.game.play_area.rect.w; const int Y = param.game.play_area.center_y; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 20); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 0.33f); // 20 frames → segundos paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } @@ -1033,7 +1033,7 @@ void Game::initPaths() { const int Y1 = param.game.play_area.center_y - (H / 2); const int Y2 = -H; const int X = param.game.play_area.center_x; - paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 20); + paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 0.33f); // 20 frames → segundos paths_.emplace_back(createPath(Y1, Y2, PathType::VERTICAL, X, 80, easeInQuint), 0); } @@ -1046,7 +1046,7 @@ void Game::initPaths() { const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = param.game.play_area.rect.w; const int Y = param.game.play_area.center_y - (H / 2) - 20; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 400); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 6.67f); // 400 frames → segundos paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } @@ -1059,7 +1059,7 @@ void Game::initPaths() { const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = -W; const int Y = param.game.play_area.center_y + (H / 2) - 20; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 400); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 6.67f); // 400 frames → segundos paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } } @@ -1660,9 +1660,12 @@ void Game::updateDemo() { fade_in_->update(); fade_out_->update(); - // Incrementa el contador de la demo - if (demo_.counter < TOTAL_DEMO_DATA) { + // Incrementa el contador de la demo cada 1/60 segundos (16.67ms) + static float demo_frame_timer = 0.0f; + demo_frame_timer += calculateDeltaTime(); + if (demo_frame_timer >= 0.01667f && demo_.counter < TOTAL_DEMO_DATA) { demo_.counter++; + demo_frame_timer -= 0.01667f; // Mantener precisión acumulada } // Activa el fundido antes de acabar con los datos de la demo @@ -1686,9 +1689,13 @@ void Game::updateRecording() { // Solo mira y guarda el input en cada update checkInput(); - // Incrementa el contador de la demo - if (demo_.counter < TOTAL_DEMO_DATA) + // Incrementa el contador de la demo cada 1/60 segundos (16.67ms) + static float recording_frame_timer = 0.0f; + recording_frame_timer += calculateDeltaTime(); + if (recording_frame_timer >= 0.01667f && demo_.counter < TOTAL_DEMO_DATA) { demo_.counter++; + recording_frame_timer -= 0.01667f; // Mantener precisión acumulada + } // Si se ha llenado el vector con datos, sale del programa else { @@ -1740,6 +1747,7 @@ void Game::updateGameStateShowingGetReadyMessage(float deltaTime) { if (music_timer >= 1.67f) { playMusic(); music_started = true; + setState(State::PLAYING); } } }