netejant capçaleres

This commit is contained in:
2025-11-11 13:02:25 +01:00
parent d6ced94316
commit 580e52a51e
8 changed files with 697 additions and 69 deletions

View File

@@ -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
```

View File

@@ -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<SDL_Texture>(...)
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 <archivo_refactorizado>
```
## 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
```

View File

@@ -160,8 +160,112 @@ Cuando uses este comando en una clase específica:
5. **Identificar** arrays C-style que convertir a std::array 5. **Identificar** arrays C-style que convertir a std::array
6. **Reorganizar** la estructura de la clase (public/private, agrupación) 6. **Reorganizar** la estructura de la clase (public/private, agrupación)
7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes 7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes
8. **Verificar** que compile correctamente 8. **Compilar** para verificar sintaxis correcta
9. **Informar** al usuario de los cambios realizados 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 ## Notas Importantes
@@ -169,3 +273,7 @@ Cuando uses este comando en una clase específica:
- **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso - **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso
- **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado) - **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado)
- **Validar compilación**: Siempre verificar que compile después de cambios - **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

View File

@@ -1,7 +1,9 @@
{ {
"permissions": { "permissions": {
"allow": [ "allow": [
"Bash(cmake --build:*)" "Bash(cmake --build:*)",
"Bash(test:*)",
"Bash(tools/linter/run_clang-tidy.sh:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

View File

@@ -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. **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 ```bash
# Analyze a specific file (RECOMMENDED) # 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 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.
--- ---

View File

@@ -14,32 +14,29 @@ SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_F
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos) SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
: SurfaceSprite(std::move(surface), pos), : SurfaceSprite(std::move(surface), pos),
x_(pos.x), x_(pos.x),
y_(pos.y), y_(pos.y) { SurfaceSprite::pos_ = pos; }
flip_(SDL_FLIP_NONE) { SurfaceSprite::pos_ = pos; }
SurfaceMovingSprite::SurfaceMovingSprite() SurfaceMovingSprite::SurfaceMovingSprite() { SurfaceSprite::clear(); }
: x_(0.0F),
y_(0.0F),
flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); }
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface) SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface)
: SurfaceSprite(std::move(surface)), : SurfaceSprite(std::move(surface)) { SurfaceSprite::clear(); }
x_(0.0F),
y_(0.0F),
flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); }
// Reinicia todas las variables // Reinicia todas las variables
void SurfaceMovingSprite::clear() { void SurfaceMovingSprite::clear() {
x_ = 0.0F; // Posición en el eje X // Resetea posición
y_ = 0.0F; // Posición en el eje Y x_ = 0.0F;
y_ = 0.0F;
vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse // Resetea velocidad
vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse vx_ = 0.0F;
vy_ = 0.0F;
ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad // Resetea aceleración
ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad 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(); SurfaceSprite::clear();
} }

View File

@@ -10,73 +10,68 @@ class Surface; // lines 8-8
// Clase SMovingSprite. Añade movimiento y flip al sprite // Clase SMovingSprite. Añade movimiento y flip al sprite
class SurfaceMovingSprite : public SurfaceSprite { class SurfaceMovingSprite : public SurfaceSprite {
public: public:
protected: // Constructores
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
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip); SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos); SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
explicit SurfaceMovingSprite(); explicit SurfaceMovingSprite();
explicit SurfaceMovingSprite(std::shared_ptr<Surface> surface); explicit SurfaceMovingSprite(std::shared_ptr<Surface> surface);
// Destructor
~SurfaceMovingSprite() override = default; ~SurfaceMovingSprite() override = default;
// Actualiza las variables internas del objeto (time-based) // Actualización y renderizado
void update(float delta_time) override; 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 // Gestión de estado
void clear() override; void clear() override; // Reinicia todas las variables a cero
// Muestra el sprite por pantalla // Getters de posición
void render() override;
void render(Uint8 source_color, Uint8 target_color) override;
// Obtiene la variable
[[nodiscard]] auto getPosX() const -> float { return x_; } [[nodiscard]] auto getPosX() const -> float { return x_; }
[[nodiscard]] auto getPosY() const -> float { return y_; } [[nodiscard]] auto getPosY() const -> float { return y_; }
// Getters de velocidad
[[nodiscard]] auto getVelX() const -> float { return vx_; } [[nodiscard]] auto getVelX() const -> float { return vx_; }
[[nodiscard]] auto getVelY() const -> float { return vy_; } [[nodiscard]] auto getVelY() const -> float { return vy_; }
// Getters de aceleración
[[nodiscard]] auto getAccelX() const -> float { return ax_; } [[nodiscard]] auto getAccelX() const -> float { return ax_; }
[[nodiscard]] auto getAccelY() const -> float { return ay_; } [[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 setVelX(float value) { vx_ = value; }
void setVelY(float value) { vy_ = value; } void setVelY(float value) { vy_ = value; }
// Setters de aceleración
void setAccelX(float value) { ax_ = value; } void setAccelX(float value) { ax_ = value; }
void setAccelY(float value) { ay_ = value; } void setAccelY(float value) { ay_ = value; }
// Establece el valor de la variable // Gestión de flip (volteo horizontal)
void setFlip(SDL_FlipMode flip) { flip_ = flip; } 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 protected:
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } // Métodos protegidos
void move(float delta_time); // Mueve el sprite (time-based)
// Obtiene el valor de la variable // Variables miembro - Posición
auto getFlip() -> SDL_FlipMode { return flip_; } 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 // Variables miembro - Velocidad (pixels/segundo)
void setPos(SDL_FRect rect); float vx_{0.0F}; // Velocidad en el eje X
float vy_{0.0F}; // Velocidad en el eje Y
// Establece el valor de las variables // Variables miembro - Aceleración (pixels/segundo²)
void setPos(float x, float y); 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 // Variables miembro - Renderizado
void setPosX(float value); SDL_FlipMode flip_{SDL_FLIP_NONE}; // Modo de volteo del sprite
// Establece el valor de la variable
void setPosY(float value);
}; };

View File

@@ -45,8 +45,8 @@ void SurfaceSprite::setPosition(SDL_FPoint p) {
// Reinicia las variables a cero // Reinicia las variables a cero
void SurfaceSprite::clear() { void SurfaceSprite::clear() {
pos_ = {0.0F, 0.0F, 0.0F, 0.0F}; pos_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
clip_ = {0.0F, 0.0F, 0.0F, 0.0F}; clip_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
} }
// Actualiza el estado del sprite (time-based) // Actualiza el estado del sprite (time-based)