diff --git a/.claude/commands/lint-clang-tidy.md b/.claude/commands/lint-clang-tidy.md new file mode 100644 index 0000000..45983ea --- /dev/null +++ b/.claude/commands/lint-clang-tidy.md @@ -0,0 +1,172 @@ +--- +description: Ejecuta clang-tidy en archivos C++ y analiza los resultados +--- + +# Lint clang-tidy Command + +Ejecuta análisis estático con clang-tidy en archivos C++ específicos, analiza los resultados inteligentemente, e identifica issues reales vs falsos positivos. + +## Propósito + +clang-tidy detecta: +- Oportunidades de modernización C++ (auto, range-for, etc.) +- Problemas de legibilidad del código +- Potenciales bugs y memory leaks +- Optimizaciones de performance +- Violaciones de mejores prácticas + +## Workflow de Ejecución + +1. **Solicitar archivos al usuario** (si no se especifican) + - Pedir rutas de archivos `.cpp` o `.hpp` a analizar + - Validar que los archivos existen + +2. **Verificar build directory** + - Confirmar que `build/compile_commands.json` existe + - Si no existe, informar al usuario que debe compilar primero + +3. **Ejecutar clang-tidy (sin --fix)** + ```bash + tools/linter/run_clang-tidy.sh archivo1.cpp archivo2.hpp + ``` + +4. **Capturar y analizar salida** + - Parsear mensajes de error/warning + - Clasificar por categoría (modernize, readability, performance, bugprone, etc.) + - Identificar falsos positivos conocidos + +5. **Presentar resumen al usuario** + - Agrupar por tipo de issue + - Separar "Críticos" vs "Recomendaciones" vs "Falsos Positivos" + - Mostrar líneas de código afectadas con contexto + +6. **Ofrecer acciones** + - Preguntar si aplicar `--fix` automáticamente + - Si el usuario acepta, ejecutar con `--fix` y recompilar + +## Falsos Positivos Conocidos + +Ignorar o marcar como "Opcional" estos casos: + +### `readability-magic-numbers` / `cppcoreguidelines-avoid-magic-numbers` +- **Contexto:** Game constants (block sizes, velocities, timers) +- **Ejemplo:** `const int BLOCK = 16;`, `player.vx = 3.0F;` +- **Acción:** Marcar como "Opcional - Game constant" + +### `modernize-use-trailing-return-type` +- **Contexto:** Funciones con tipos de retorno simples +- **Ejemplo:** `int getValue() { return x_; }` +- **Acción:** Marcar como "Opcional - Style preference" + +### Errores en `defaults.hpp` +- **Contexto:** Archivos de constantes del juego +- **Acción:** Ignorar completamente, mencionar al usuario que es conocido + +### `readability-identifier-length` +- **Contexto:** Variables cortas comunes en loops o coordenadas (`x`, `y`, `i`, `j`) +- **Acción:** Marcar como "Opcional - Common convention" + +## Categorización de Issues + +### 🔴 Críticos (Requieren atención) +- `bugprone-*`: Potenciales bugs +- `cert-*`: Security issues +- Memory leaks y null pointer dereferences +- Undefined behavior + +### 🟡 Recomendados (Mejoran calidad) +- `modernize-*`: C++20 modernization +- `performance-*`: Optimizaciones +- `readability-*`: Mejoras de legibilidad (excepto magic-numbers) + +### ⚪ Opcionales (A criterio) +- `readability-magic-numbers` en game constants +- `modernize-use-trailing-return-type` +- `readability-identifier-length` para `x`, `y`, `i`, `j` + +### ⚫ Ignorar (Falsos positivos) +- Errores en `defaults.hpp` +- Issues en carpeta `external/` +- Warnings en headers del sistema + +## Formato de Reporte al Usuario + +``` +=== clang-tidy Analysis Results === + +📁 Archivos analizados: + - source/game/entities/player.cpp + - source/game/entities/player.hpp + +🔴 Críticos (2): + player.cpp:145 [bugprone-use-after-move] - Uso de variable después de std::move() + player.cpp:230 [cert-err58-cpp] - Excepción en inicialización estática + +🟡 Recomendados (5): + player.cpp:67 [modernize-use-auto] - Puede usar 'auto' en lugar de tipo explícito + player.cpp:102 [performance-unnecessary-copy-initialization] - Copia innecesaria + player.hpp:23 [readability-redundant-access-specifiers] - Especificador de acceso redundante + +⚪ Opcionales (3): + player.cpp:88 [readability-magic-numbers] - Magic number '16' (Game constant: BLOCK size) + player.cpp:120 [modernize-use-trailing-return-type] - Style preference + +✅ Total: 10 issues (2 críticos, 5 recomendados, 3 opcionales) + +--- + +💡 Recomendaciones: +1. Corregir los 2 issues críticos manualmente +2. Aplicar --fix para 5 recomendaciones (revisa cambios antes de commitear) +3. Los opcionales son aceptables en código de juego + +¿Deseas aplicar fixes automáticos para los issues recomendados? (y/n) +``` + +## Aplicar Fixes Automáticos + +Si el usuario acepta: + +1. **Ejecutar con --fix** + ```bash + tools/linter/run_clang-tidy.sh --fix archivo1.cpp archivo2.hpp + ``` + +2. **Informar cambios** + - Listar archivos modificados + - Recomendar revisión manual + +3. **Recompilar** + ```bash + cmake --build build + ``` + +4. **Verificar compilación exitosa** + - Si falla, informar errores + - Sugerir revertir cambios si es necesario + +## Notas Importantes + +- **Siempre analizar sin --fix primero** para revisar cambios propuestos +- **Requiere build/compile_commands.json** - el usuario debe haber compilado antes +- **Contexto importa** - Game code tiene patrones legítimos que linters marcan como issues +- **No aplicar --fix ciegamente** - Algunos fixes pueden romper lógica del juego +- **Archivos específicos** - Siempre analizar archivos concretos, no todo el proyecto + +## Integración con Otros Comandos + +Este comando puede ser llamado desde: +- `/refactor-class` - Después de refactorizar una clase +- Manualmente por el usuario para análisis ad-hoc +- Antes de commits importantes + +--- + +**Uso:** +``` +/lint-clang-tidy +(El comando preguntará qué archivos analizar) + +O especificar directamente: +/lint-clang-tidy source/game/entities/player.cpp +``` diff --git a/.claude/commands/lint-cppcheck.md b/.claude/commands/lint-cppcheck.md new file mode 100644 index 0000000..2aae622 --- /dev/null +++ b/.claude/commands/lint-cppcheck.md @@ -0,0 +1,275 @@ +--- +description: Ejecuta cppcheck en código C++ y analiza resultados +--- + +# Lint cppcheck Command + +Ejecuta análisis estático con cppcheck en código C++, filtra noise, e identifica issues reales relacionados con bugs, memory safety y undefined behavior. + +## Propósito + +cppcheck detecta: +- Memory leaks y resource leaks +- Null pointer dereferences +- Buffer overflows y array bounds issues +- Uninitialized variables +- Dead code y unused functions +- Style issues y code smells +- Undefined behavior + +## Workflow de Ejecución + +1. **Solicitar archivos/rutas al usuario** (si no se especifican) + - Pedir rutas de archivos `.cpp`/`.hpp` o carpetas a analizar + - Preguntar nivel de análisis (warning/all/unused) + - Default: `-w` (warning, style, performance) + +2. **Validar precondiciones** + - Confirmar que los archivos/carpetas existen + - Si no existe `build/compile_commands.json`, el script lo generará automáticamente + +3. **Ejecutar cppcheck** + ```bash + # Para archivo específico + tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp + + # Para carpeta + tools/linter/run_cppcheck.sh -w --path source/game/entities/ + + # Proyecto completo (LENTO) + tools/linter/run_cppcheck.sh -w + ``` + +4. **Leer archivo de resultados** + - `-w`: `tools/linter/cppcheck-result-warning-style-performance.txt` + - `-a`: `tools/linter/cppcheck-result-all.txt` + - `-u`: `tools/linter/cppcheck-result-unusedFunction.txt` + +5. **Analizar y clasificar issues** + - Parsear formato de cppcheck: `[archivo:línea]: (severidad) mensaje` + - Filtrar falsos positivos conocidos + - Agrupar por categoría + +6. **Presentar resumen al usuario** + - Mostrar issues críticos primero + - Explicar contexto cuando sea relevante + - Sugerir acciones correctivas + +## Niveles de Análisis + +### `-w` / `--warning` (Recomendado para uso diario) +- **Velocidad:** Rápido +- **Checks:** warning, style, performance +- **Uso:** Refactoring diario, antes de commits +- **Ejemplo:** `tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp` + +### `-a` / `--all` (Análisis exhaustivo) +- **Velocidad:** Lento +- **Checks:** Todos los checks disponibles +- **Uso:** Después de cambios mayores, auditorías de código +- **Ejemplo:** `tools/linter/run_cppcheck.sh -a --path source/game/` + +### `-u` / `--unused` (Funciones no usadas) +- **Velocidad:** Medio +- **Checks:** unusedFunction +- **Uso:** Limpieza de código muerto +- **Ejemplo:** `tools/linter/run_cppcheck.sh -u` +- **Nota:** Requiere análisis de proyecto completo + +## Falsos Positivos Conocidos + +### `unusedFunction` en métodos públicos +- **Contexto:** Métodos de API pública, callbacks, getters/setters +- **Ejemplo:** `Player::getX()` usado desde múltiples lugares +- **Acción:** Ignorar si el método es parte de la interfaz pública + +### `passedByValue` para tipos pequeños +- **Contexto:** SDL_FRect, SDL_Point, enums, small structs +- **Ejemplo:** `void setPos(SDL_FPoint pos)` +- **Acción:** Aceptable para tipos ≤ 16 bytes en game code + +### `constParameter` en APIs consistentes +- **Contexto:** Parámetros que no se modifican pero mantienen consistencia de API +- **Acción:** Opcional, depende de estilo del proyecto + +### `variableScope` en inicializaciones complejas +- **Contexto:** Variables declaradas antes de inicialización compleja +- **Acción:** Revisar caso por caso, puede ser falso positivo + +## Categorización de Issues + +### 🔴 Críticos (Requieren corrección inmediata) +- `error`: Bugs confirmados +- `memleakOnRealloc`: Memory leaks +- `nullPointer`: Null pointer dereferences +- `bufferAccessOutOfBounds`: Buffer overflows +- `uninitvar`: Variables no inicializadas +- `useAfterFree`: Use-after-free + +### 🟠 Advertencias (Revisar y corregir) +- `warning`: Potenciales problemas +- `memleak`: Posibles memory leaks +- `resourceLeak`: Resource leaks (file handles, etc.) +- `doubleFree`: Double free +- `arrayIndexOutOfBounds`: Array bounds issues + +### 🟡 Estilo (Mejoran calidad) +- `style`: Code smells +- `unusedVariable`: Variables no usadas +- `redundantAssignment`: Asignaciones redundantes +- `unreadVariable`: Variables escritas pero no leídas + +### 🟢 Performance (Optimizaciones) +- `performance`: Optimizaciones de rendimiento +- `passedByValue`: Pasar por const& en vez de value +- `postfixOperator`: Usar prefix++ en vez de postfix++ + +### ⚪ Informativo (Opcional) +- `information`: Información general +- `portability`: Problemas de portabilidad +- `unusedFunction`: Funciones no usadas (revisar contexto) + +## Formato de Reporte al Usuario + +``` +=== cppcheck Analysis Results === + +📁 Archivos analizados: source/game/entities/player.cpp +📊 Nivel: warning + style + performance +📝 Resultados: tools/linter/cppcheck-result-warning-style-performance.txt + +🔴 Errores críticos (2): + player.cpp:156 [error:uninitvar] - Variable 'velocity' no inicializada + player.cpp:234 [error:nullPointer] - Posible null pointer dereference + +🟠 Advertencias (3): + player.cpp:89 [warning:memleak] - Posible memory leak en 'sprite_' + player.cpp:178 [warning:arrayIndexOutOfBounds] - Índice fuera de límites + +🟡 Estilo (4): + player.cpp:45 [style:unusedVariable] - Variable 'temp' declarada pero no usada + player.cpp:102 [style:redundantAssignment] - Asignación redundante a 'x_' + +🟢 Performance (2): + player.cpp:67 [performance:passedByValue] - Pasar 'data' por const& (8 bytes - FALSO POSITIVO) + player.hpp:34 [performance:postfixOperator] - Usar prefix++ en lugar de postfix++ + +✅ Total: 11 issues + - 2 críticos ❗ + - 3 advertencias + - 4 estilo + - 2 performance (1 falso positivo) + +--- + +💡 Acción requerida: +1. ✅ Corregir 2 errores críticos INMEDIATAMENTE +2. ⚠️ Revisar 3 advertencias y corregir si aplica +3. 🔧 Considerar 4 mejoras de estilo +4. ⚡ 1 optimización real de performance (ignorar passedByValue) + +📄 Detalles completos en: tools/linter/cppcheck-result-warning-style-performance.txt +``` + +## Acciones Post-Análisis + +### Si hay errores críticos: +1. **Mostrar código afectado** con contexto +2. **Explicar el problema** en términos claros +3. **Sugerir corrección** específica +4. **Ofrecer aplicar fix** si es sencillo + +### Si solo hay warnings/style: +1. **Resumir issues** por categoría +2. **Indicar prioridades** (qué corregir primero) +3. **Explicar falsos positivos** identificados +4. **Preguntar si aplicar fixes** para issues simples + +### Si no hay issues: +``` +✅ ¡Código limpio! No se encontraron issues. +``` + +## Ejemplos de Correcciones Comunes + +### Uninitialized variable +```cpp +// ❌ Antes +int velocity; +if (condition) { + velocity = 10; +} +use(velocity); // Error: puede estar no inicializada + +// ✅ Después +int velocity{0}; // Inicializar en declaración +if (condition) { + velocity = 10; +} +use(velocity); +``` + +### Memory leak +```cpp +// ❌ Antes +void loadTexture() { + texture_ = new SDL_Texture(...); + if (error) return; // Leak si hay error después +} + +// ✅ Después +void loadTexture() { + auto temp = std::make_unique(...) + if (error) return; // RAII - se libera automáticamente + texture_ = std::move(temp); +} +``` + +### Null pointer dereference +```cpp +// ❌ Antes +Player* player = getPlayer(); +player->update(); // Puede ser nullptr + +// ✅ Después +Player* player = getPlayer(); +if (player != nullptr) { + player->update(); +} +``` + +## Integración con Workflow + +### Cuándo ejecutar: + +1. **Después de refactoring** - Verificar que no se introdujeron bugs +2. **Antes de commit** - Análisis `-w` rápido +3. **Antes de PR** - Análisis `-a` completo +4. **Periódicamente** - Análisis `-u` para limpieza de código + +### Integración con `/refactor-class`: + +El comando `/refactor-class` ejecuta automáticamente: +```bash +tools/linter/run_cppcheck.sh -w --path +``` + +## Notas Importantes + +- **Genera archivos de salida** en `tools/linter/cppcheck-result-*.txt` +- **Auto-genera compile_commands.json** si no existe +- **Paralelización automática** usa N-1 cores +- **Suppressions file** excluye external/ y system headers +- **Contexto importa** - Revisar falsos positivos manualmente +- **No modifica código** - Solo reporta, no aplica fixes automáticos + +--- + +**Uso:** +``` +/lint-cppcheck +(El comando preguntará qué analizar y qué nivel usar) + +O especificar directamente: +/lint-cppcheck source/game/entities/player.cpp +``` diff --git a/.claude/commands/refactor-class.md b/.claude/commands/refactor-class.md index f1f1d2d..b871008 100644 --- a/.claude/commands/refactor-class.md +++ b/.claude/commands/refactor-class.md @@ -160,8 +160,112 @@ Cuando uses este comando en una clase específica: 5. **Identificar** arrays C-style que convertir a std::array 6. **Reorganizar** la estructura de la clase (public/private, agrupación) 7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes -8. **Verificar** que compile correctamente -9. **Informar** al usuario de los cambios realizados +8. **Compilar** para verificar sintaxis correcta +9. **Ejecutar clang-tidy** (análisis, sin --fix) y revisar resultados +10. **Ejecutar cppcheck** (nivel -w) y revisar resultados +11. **Aplicar fixes apropiados** basados en análisis de linters +12. **Recompilar** si se aplicaron fixes +13. **Reportar resumen** al usuario: cambios + hallazgos de linters + +## Workflow de Linters (Pasos 9-12) + +### Paso 9: Ejecutar clang-tidy + +```bash +tools/linter/run_clang-tidy.sh archivo.cpp archivo.hpp +``` + +**Analizar resultados:** +- Identificar issues críticos (bugprone, cert) +- Separar recomendaciones válidas de falsos positivos +- Ignorar: magic-numbers en game constants, defaults.hpp errors +- Si hay issues críticos, informar al usuario y pausar +- Si solo hay recomendaciones, continuar + +### Paso 10: Ejecutar cppcheck + +```bash +tools/linter/run_cppcheck.sh -w --path archivo.cpp +``` + +**Leer archivo de resultados:** +- `tools/linter/cppcheck-result-warning-style-performance.txt` +- Identificar errores críticos (error, nullPointer, uninitvar) +- Separar warnings de style issues +- Filtrar falsos positivos (passedByValue para tipos pequeños, unusedFunction en API pública) +- Si hay errores críticos, informar al usuario y pausar + +### Paso 11: Aplicar Fixes + +**Si hay issues aplicables:** + +1. **Fixes automáticos de clang-tidy** (solo si son seguros): + - modernize-use-auto + - readability-redundant-access-specifiers + - Performance optimizations claras + + ```bash + tools/linter/run_clang-tidy.sh --fix archivo.cpp archivo.hpp + ``` + +2. **Fixes manuales necesarios:** + - Inicializar variables no inicializadas + - Corregir null pointer issues + - Resolver memory leaks + +3. **Documentar cambios** para el reporte final + +### Paso 12: Recompilar + +Si se aplicaron fixes en paso 11: + +```bash +cmake --build build +``` + +**Verificar:** +- ✅ Compilación exitosa → Continuar a reporte +- ❌ Errores → Informar al usuario, sugerir revisión manual + +## Formato de Reporte Final (Paso 13) + +``` +=== Refactor Completado: ClassName === + +📝 Cambios estructurales: + ✅ #pragma once aplicado + ✅ 3 structs actualizados con valores por defecto + ✅ 12 variables movidas a inicialización en declaración + ✅ 2 arrays C-style → std::array + ✅ Clase reorganizada (public primero, variables al final) + ✅ Constructor simplificado (elimina 12 inicializaciones redundantes) + +🔍 Análisis de linters: + +clang-tidy: + ✅ Sin issues críticos + 🟡 3 recomendaciones aplicadas automáticamente: + - Modernize: use auto (2 lugares) + - Readability: redundant specifier (1 lugar) + ⚪ 2 opcionales ignorados: + - magic-numbers en game constants + +cppcheck: + ✅ Sin errores + 🟡 2 style issues encontrados: + - Unused variable 'temp' en línea 45 → Eliminada + - Redundant assignment en línea 102 → Corregida + +📊 Resultado: + ✅ Compilación exitosa + ✅ Todos los linters pasan sin issues críticos + ✅ Código refactorizado y verificado + +💡 Próximos pasos: + - Revisar cambios manualmente + - Ejecutar tests si existen + - Commitear con mensaje descriptivo +``` ## Notas Importantes @@ -169,3 +273,7 @@ Cuando uses este comando en una clase específica: - **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso - **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado) - **Validar compilación**: Siempre verificar que compile después de cambios +- **Linters integrados**: Análisis automático post-refactor para garantizar calidad +- **Fixes inteligentes**: Solo aplicar --fix de clang-tidy si los cambios son seguros +- **Contexto importa**: Game code tiene patrones legítimos (magic numbers, etc.) +- **Falsos positivos**: Identificar y documentar, no corregir ciegamente diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 04d6a79..7410051 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,7 +1,9 @@ { "permissions": { "allow": [ - "Bash(cmake --build:*)" + "Bash(cmake --build:*)", + "Bash(test:*)", + "Bash(tools/linter/run_clang-tidy.sh:*)" ], "deny": [], "ask": [] diff --git a/CLAUDE.md b/CLAUDE.md index 3849866..daa3151 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,9 +55,15 @@ cmake --build build --clean-first **Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory. -### Linter (clang-tidy) +### Static Analysis Tools (Linters) -**IMPORTANT:** Always run the linter on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files. +This project uses two complementary static analysis tools for code quality: + +#### clang-tidy (Modernization & Best Practices) + +**Purpose:** Detects style issues, modernization opportunities, and potential bugs. Best for refactoring and applying C++20 best practices. + +**IMPORTANT:** Always run on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files. ```bash # Analyze a specific file (RECOMMENDED) @@ -73,7 +79,80 @@ tools/linter/run_clang-tidy.sh --fix source/game/entities/player.cpp tools/linter/run_clang-tidy.sh ``` -**Note:** Running the linter on the entire project can produce errors in files like `defaults.hpp` that are unrelated to your changes. Always target specific files you're working on. +**Common clang-tidy Checks:** +- `modernize-*`: C++ modernization (use auto, range-for, etc.) +- `readability-*`: Code readability improvements +- `performance-*`: Performance optimizations +- `bugprone-*`: Potential bug detection + +**Known False Positives:** +- `defaults.hpp`: May report errors in constant definitions +- `readability-magic-numbers`: Acceptable for game constants (block sizes, speeds, etc.) +- `cppcoreguidelines-avoid-magic-numbers`: Same as above, acceptable in game code + +#### cppcheck (Bug Detection & Memory Safety) + +**Purpose:** Detects bugs, memory leaks, undefined behavior, and style issues. Complementary to clang-tidy. + +```bash +# Warning, style, and performance analysis (RECOMMENDED for daily use) +tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp + +# Exhaustive analysis (slower, more thorough) +tools/linter/run_cppcheck.sh -a --path source/game/entities/ + +# Detect unused functions (whole project analysis) +tools/linter/run_cppcheck.sh -u + +# Analyze entire project with warning level +tools/linter/run_cppcheck.sh -w +``` + +**Output:** Results are saved in `tools/linter/cppcheck-result-*.txt` + +**Common cppcheck Checks:** +- Memory leaks and resource management +- Null pointer dereferences +- Buffer overflows and array bounds +- Uninitialized variables +- Dead code and unused functions + +**Known False Positives:** +- `unusedFunction`: May report false positives for callback functions or public API methods +- `passedByValue`: Acceptable for small types like SDL_FRect in game code +- `constParameter`: Not always applicable for API consistency + +#### When to Use Each Tool + +| Scenario | Tool | Reason | +|----------|------|--------| +| **Daily refactoring** | clang-tidy | Fast, auto-fixable issues | +| **Before committing** | Both | Comprehensive quality check | +| **After major changes** | cppcheck -a | Deep bug analysis | +| **Hunting memory leaks** | cppcheck | Specialized detection | +| **Code modernization** | clang-tidy --fix | Automatic C++20 upgrades | + +#### Best Practices + +1. **Run linters after compilation succeeds** - Fix compile errors first +2. **Analyze specific files** - Faster feedback, avoids unrelated errors +3. **Review before applying --fix** - Understand changes before accepting +4. **Context matters** - Game code may legitimately have "magic numbers" for gameplay constants +5. **Use both tools** - They catch different issues and complement each other +6. **Check suppressions file** - `tools/linter/cppcheck_suppressions` excludes external/ and system headers + +#### Integration with Development Workflow + +When refactoring code (especially with `/refactor-class` command): +1. Make structural changes +2. **Compile** to verify syntax +3. **Run clang-tidy** (without --fix) to identify issues +4. **Run cppcheck -w** to catch bugs +5. Review and fix legitimate issues +6. Apply automatic fixes if appropriate +7. Recompile and test + +**Note:** The `/refactor-class` command automatically runs both linters after compilation and provides intelligent analysis of results. --- diff --git a/source/core/rendering/surface_moving_sprite.cpp b/source/core/rendering/surface_moving_sprite.cpp index b7964ac..feae05e 100644 --- a/source/core/rendering/surface_moving_sprite.cpp +++ b/source/core/rendering/surface_moving_sprite.cpp @@ -14,32 +14,29 @@ SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr surface, SDL_F SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr surface, SDL_FRect pos) : SurfaceSprite(std::move(surface), pos), x_(pos.x), - y_(pos.y), - flip_(SDL_FLIP_NONE) { SurfaceSprite::pos_ = pos; } + y_(pos.y) { SurfaceSprite::pos_ = pos; } -SurfaceMovingSprite::SurfaceMovingSprite() - : x_(0.0F), - y_(0.0F), - flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); } +SurfaceMovingSprite::SurfaceMovingSprite() { SurfaceSprite::clear(); } SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr surface) - : SurfaceSprite(std::move(surface)), - x_(0.0F), - y_(0.0F), - flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); } + : SurfaceSprite(std::move(surface)) { SurfaceSprite::clear(); } // Reinicia todas las variables void SurfaceMovingSprite::clear() { - x_ = 0.0F; // Posición en el eje X - y_ = 0.0F; // Posición en el eje Y + // Resetea posición + x_ = 0.0F; + y_ = 0.0F; - vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse - vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse + // Resetea velocidad + vx_ = 0.0F; + vy_ = 0.0F; - ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad - ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad + // Resetea aceleración + ax_ = 0.0F; + ay_ = 0.0F; - flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite + // Resetea flip + flip_ = SDL_FLIP_NONE; SurfaceSprite::clear(); } diff --git a/source/core/rendering/surface_moving_sprite.hpp b/source/core/rendering/surface_moving_sprite.hpp index 227998f..4d0134b 100644 --- a/source/core/rendering/surface_moving_sprite.hpp +++ b/source/core/rendering/surface_moving_sprite.hpp @@ -10,73 +10,68 @@ class Surface; // lines 8-8 // Clase SMovingSprite. Añade movimiento y flip al sprite class SurfaceMovingSprite : public SurfaceSprite { public: - protected: - float x_; // Posición en el eje X - float y_; // Posición en el eje Y - - float vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse - float vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse - - float ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad - float ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad - - SDL_FlipMode flip_; // Indica como se voltea el sprite - - // Mueve el sprite (time-based) - void move(float delta_time); - - public: - // Constructor + // Constructores SurfaceMovingSprite(std::shared_ptr surface, SDL_FRect pos, SDL_FlipMode flip); SurfaceMovingSprite(std::shared_ptr surface, SDL_FRect pos); explicit SurfaceMovingSprite(); explicit SurfaceMovingSprite(std::shared_ptr surface); - - // Destructor ~SurfaceMovingSprite() override = default; - // Actualiza las variables internas del objeto (time-based) - void update(float delta_time) override; + // Actualización y renderizado + void update(float delta_time) override; // Actualiza variables internas (time-based) + void render() override; // Muestra el sprite por pantalla + void render(Uint8 source_color, Uint8 target_color) override; // Renderiza con reemplazo de color - // Reinicia todas las variables a cero - void clear() override; + // Gestión de estado + void clear() override; // Reinicia todas las variables a cero - // Muestra el sprite por pantalla - void render() override; - void render(Uint8 source_color, Uint8 target_color) override; - - // Obtiene la variable + // Getters de posición [[nodiscard]] auto getPosX() const -> float { return x_; } [[nodiscard]] auto getPosY() const -> float { return y_; } + + // Getters de velocidad [[nodiscard]] auto getVelX() const -> float { return vx_; } [[nodiscard]] auto getVelY() const -> float { return vy_; } + + // Getters de aceleración [[nodiscard]] auto getAccelX() const -> float { return ax_; } [[nodiscard]] auto getAccelY() const -> float { return ay_; } - // Establece la variable + // Setters de posición + void setPos(SDL_FRect rect); // Establece posición y tamaño del objeto + void setPos(float x, float y); // Establece posición x, y + void setPosX(float value); // Establece posición X + void setPosY(float value); // Establece posición Y + + // Setters de velocidad void setVelX(float value) { vx_ = value; } void setVelY(float value) { vy_ = value; } + + // Setters de aceleración void setAccelX(float value) { ax_ = value; } void setAccelY(float value) { ay_ = value; } - // Establece el valor de la variable - void setFlip(SDL_FlipMode flip) { flip_ = flip; } + // Gestión de flip (volteo horizontal) + void setFlip(SDL_FlipMode flip) { flip_ = flip; } // Establece modo de flip + auto getFlip() -> SDL_FlipMode { return flip_; } // Obtiene modo de flip + void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } // Alterna flip horizontal - // Gira el sprite horizontalmente - void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } + protected: + // Métodos protegidos + void move(float delta_time); // Mueve el sprite (time-based) - // Obtiene el valor de la variable - auto getFlip() -> SDL_FlipMode { return flip_; } + // Variables miembro - Posición + float x_{0.0F}; // Posición en el eje X + float y_{0.0F}; // Posición en el eje Y - // Establece la posición y_ el tamaño del objeto - void setPos(SDL_FRect rect); + // Variables miembro - Velocidad (pixels/segundo) + float vx_{0.0F}; // Velocidad en el eje X + float vy_{0.0F}; // Velocidad en el eje Y - // Establece el valor de las variables - void setPos(float x, float y); + // Variables miembro - Aceleración (pixels/segundo²) + float ax_{0.0F}; // Aceleración en el eje X + float ay_{0.0F}; // Aceleración en el eje Y - // Establece el valor de la variable - void setPosX(float value); - - // Establece el valor de la variable - void setPosY(float value); + // Variables miembro - Renderizado + SDL_FlipMode flip_{SDL_FLIP_NONE}; // Modo de volteo del sprite }; \ No newline at end of file diff --git a/source/core/rendering/surface_sprite.cpp b/source/core/rendering/surface_sprite.cpp index 52923e4..d96b84e 100644 --- a/source/core/rendering/surface_sprite.cpp +++ b/source/core/rendering/surface_sprite.cpp @@ -45,8 +45,8 @@ void SurfaceSprite::setPosition(SDL_FPoint p) { // Reinicia las variables a cero void SurfaceSprite::clear() { - pos_ = {0.0F, 0.0F, 0.0F, 0.0F}; - clip_ = {0.0F, 0.0F, 0.0F, 0.0F}; + pos_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F}; + clip_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F}; } // Actualiza el estado del sprite (time-based)