Compare commits
22 Commits
568b941990
...
3fdd61655a
| Author | SHA1 | Date | |
|---|---|---|---|
| 3fdd61655a | |||
| 504727b95f | |||
| ff5446fcdf | |||
| 545eb70082 | |||
| 232a23a5dd | |||
| c9a29e26dd | |||
| 2977869ab5 | |||
| 6a223b68ba | |||
| 3fafff026b | |||
| 159528adc9 | |||
| 6c8f231b34 | |||
| c5d6d77ebf | |||
| 5e73327b2f | |||
| 720d286dcf | |||
| dd13a2bd7c | |||
| 1a6ef79466 | |||
| 8f83a1d13e | |||
| 9edfe6877f | |||
| 91b26631c6 | |||
| 331a690b78 | |||
| 5e3946e28b | |||
| d4a0189dc8 |
81
DELTATIME_MIGRATION_PLAN.md
Normal file
81
DELTATIME_MIGRATION_PLAN.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Plan de Migración DeltaTime - Eliminación de frameFactor
|
||||
|
||||
## Problema Identificado
|
||||
Se están usando `frameFactor` conversions en 7 archivos, lo que indica una migración incompleta a deltaTime.
|
||||
El patrón `float frameFactor = deltaTime / (1000.0f / 60.0f)` simula frames de 60fps en lugar de usar tiempo real.
|
||||
|
||||
## Archivos Afectados y Estado
|
||||
1. **balloon.cpp** - 9 ocurrencias en métodos: moveX(), moveY(), updateState(), updateCreation()
|
||||
2. **balloon_manager.cpp** - 2 ocurrencias en updateBalloonDeployment()
|
||||
3. **bullet.cpp** - 3 ocurrencias en move()
|
||||
4. **item.cpp** - 6 ocurrencias en move()
|
||||
5. **moving_sprite.cpp** - 5 ocurrencias en move()
|
||||
6. **tabe.cpp** - 5 ocurrencias en update() y updateHitEffect()
|
||||
7. **credits.cpp** - 3 ocurrencias en update() y handleFadeOut()
|
||||
|
||||
## Estrategia de Migración
|
||||
|
||||
### Opción A: Velocidades ya en pixels/segundo
|
||||
Si las velocidades están definidas en pixels/segundo:
|
||||
```cpp
|
||||
// ANTES (incorrecto)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
|
||||
// DESPUÉS (correcto)
|
||||
pos_x_ += vel_x_ * (deltaTime / 1000.0f); // deltaTime en ms -> segundos
|
||||
```
|
||||
|
||||
### Opción B: Velocidades en pixels/frame (legacy)
|
||||
Si las velocidades están en pixels/frame (sistema legacy):
|
||||
```cpp
|
||||
// ANTES (incorrecto con deltaTime)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
|
||||
// OPCIÓN 1: Convertir velocidades a pixels/segundo
|
||||
static constexpr float VEL_X_PER_SECOND = VEL_X_PER_FRAME * 60.0f;
|
||||
pos_x_ += VEL_X_PER_SECOND * (deltaTime / 1000.0f);
|
||||
|
||||
// OPCIÓN 2: Mantener frame-factor pero mejorar claridad
|
||||
pos_x_ += vel_x_ * (deltaTime / FRAME_TIME_MS); // donde FRAME_TIME_MS = 16.67f
|
||||
```
|
||||
|
||||
## Plan de Ejecución
|
||||
|
||||
### Fase 1: Análisis de Velocidades
|
||||
- [ ] Revisar definiciones de velocidades en cada clase
|
||||
- [ ] Determinar si están en pixels/frame o pixels/segundo
|
||||
- [ ] Identificar constantes que necesitan conversión
|
||||
|
||||
### Fase 2: Migración por Archivo
|
||||
- [x] **balloon.cpp**: Migrar velocidades x/y y contadores ✅
|
||||
- [x] **balloon_manager.cpp**: Migrar balloon_deploy_counter_ ✅
|
||||
- [x] **bullet.cpp**: Migrar velocidades de bala ✅ (VEL_Y: -3.0F→-0.18F, VEL_X: ±2.0F→±0.12F)
|
||||
- [x] **item.cpp**: Migrar física de ítems ✅ (vel_x: ±1.0F→±0.06F, vel_y: -4.0F→-0.24F, accel_y: 0.2F→0.012F)
|
||||
- [ ] **moving_sprite.cpp**: Migrar sistema base de movimiento
|
||||
- [ ] **tabe.cpp**: Migrar movimiento y efectos
|
||||
- [ ] **credits.cpp**: Migrar contadores de timing
|
||||
|
||||
### Fase 3: Verificación
|
||||
- [ ] Compilar y probar cada archivo migrado
|
||||
- [ ] Verificar que el comportamiento se mantiene consistente
|
||||
- [ ] Eliminar todas las referencias a frameFactor
|
||||
- [ ] Actualizar comentarios para reflejar unidades correctas
|
||||
|
||||
## Criterios de Éxito
|
||||
1. ✅ Cero ocurrencias de "frameFactor" en el código
|
||||
2. ✅ Todas las velocidades claramente documentadas (pixels/segundo vs pixels/frame)
|
||||
3. ✅ Comportamiento del juego idéntico al anterior
|
||||
4. ✅ Código más limpio y mantenible
|
||||
|
||||
## Notas Importantes
|
||||
- El frameFactor actual simula 60fps: `deltaTime / 16.67ms`
|
||||
- Esto significa que las velocidades actuales están en "pixels per 16.67ms"
|
||||
- Para verdadero deltaTime, necesitamos convertir a "pixels per second" o usar factor de frame explícito
|
||||
- Mantener constantes claras para evitar números mágicos
|
||||
|
||||
## Estado: En Progreso
|
||||
- Análisis iniciado
|
||||
- Plan documentado
|
||||
- Próximo paso: Análisis de velocidades en cada archivo
|
||||
@@ -8,270 +8,270 @@
|
||||
|
||||
formation: 0
|
||||
# Dos enemigos BALLOON3 uno a cada extremo
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 1
|
||||
# Dos enemigos BALLOON3 uno a cada cuarto. Ambos van hacia el centro
|
||||
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 2
|
||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 30
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 20
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 10
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 3
|
||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 30
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 20
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 10
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 4
|
||||
# Tres enemigos BALLOON2. 0, 25, 50. Hacia la derecha
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 5
|
||||
# Tres enemigos BALLOON2. 50, 75, 100. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 6
|
||||
# Tres enemigos BALLOON2. 0, 0, 0. Hacia la derecha
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 7
|
||||
# Tres enemigos BALLOON2. 100, 100, 100. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 8
|
||||
# Seis enemigos BALLOON0. 0, 0, 0, 0, 0, 0. Hacia la derecha
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 9
|
||||
# Seis enemigos BALLOON0. 100, 100, 100, 100, 100, 100. Hacia la izquierda
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 10
|
||||
# Tres enemigos BALLOON3 seguidos desde la izquierda. Hacia la derecha
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 30
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 15
|
||||
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.5000
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.2500
|
||||
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 11
|
||||
# Tres enemigos BALLOON3 seguidos desde la derecha. Hacia la izquierda
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 30
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 15
|
||||
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.5000
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.2500
|
||||
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 12
|
||||
# Seis enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 50
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 40
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 30
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 20
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 10
|
||||
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.8333
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.6667
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 13
|
||||
# Seis enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 50
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 40
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 30
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 20
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 10
|
||||
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.8333
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.6667
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 14
|
||||
# Cinco enemigos BALLOON2. Hacia la derecha. Separados
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 15
|
||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Separados
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 16
|
||||
# Cinco enemigos BALLOON2. Hacia la derecha. Juntos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 17
|
||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Juntos
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 18
|
||||
# Doce enemigos BALLOON0. Hacia la derecha. Juntos
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 110
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 100
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 90
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 80
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
||||
X0_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
||||
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
||||
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
||||
X0_0, 9, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
||||
X0_0, 10, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
||||
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.8333
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.6667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.5000
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.3333
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_0, 9, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_0, 10, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 19
|
||||
# Doce enemigos BALLOON0. Hacia la izquierda. Juntos
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 110
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 100
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 90
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 80
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
||||
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
||||
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
||||
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
||||
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
||||
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
||||
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.8333
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.6667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.5000
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.3333
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 20
|
||||
# Cuatro enemigos BALLOON3 seguidos desde la izquierda/derecha. Simétricos
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 21
|
||||
# Diez enemigos BALLOON1 uno detrás del otro. Izquierda/derecha. Simétricos
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 12
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 9
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 6
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 3
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 12
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 9
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 6
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 3
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.2000
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1500
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1000
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0500
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.2000
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1500
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1000
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0500
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 22
|
||||
# Diez enemigos BALLOON2. Hacia la derecha/izquierda. Separados. Simétricos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 23
|
||||
# Diez enemigos BALLOON2. Hacia la derecha. Juntos. Simétricos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 24
|
||||
# Treinta enemigos BALLOON0. Del centro hacia los extremos. Juntos. Simétricos
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 5
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 15
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 25
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 35
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 45
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 55
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 65
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 5
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 15
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 25
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 35
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 45
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 55
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 65
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
|
||||
formation: 25
|
||||
# Treinta enemigos BALLOON0. Del centro hacia adentro. Juntos. Simétricos
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 65
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 55
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 45
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 35
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 25
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 15
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 5
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 65
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 55
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 45
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 35
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 25
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 15
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 5
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
@@ -48,15 +48,15 @@ title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
# --- BACKGROUND ---
|
||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||
|
||||
# --- BALLOONS ---
|
||||
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
||||
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
||||
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
||||
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
||||
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
||||
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
||||
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
||||
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
||||
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||
|
||||
balloon.color[0] blue # Color de creación del globo normal
|
||||
balloon.color[1] orange # Color del globo normal
|
||||
|
||||
@@ -48,15 +48,15 @@ title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
# --- BACKGROUND ---
|
||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||
|
||||
# --- BALLOONS ---
|
||||
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
||||
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
||||
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
||||
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
||||
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
||||
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
||||
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
||||
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
||||
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||
|
||||
balloon.color[0] blue # Color de creación del globo normal
|
||||
balloon.color[1] orange # Color del globo normal
|
||||
|
||||
@@ -3,28 +3,28 @@ frame_height=10
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=26
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=48
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=10
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=26
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=48
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=49
|
||||
|
||||
[animation]
|
||||
name=powerball
|
||||
speed=10
|
||||
speed=0.0167
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -3,42 +3,42 @@ frame_height=12
|
||||
|
||||
[animation]
|
||||
name=normal_up
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=normal_left
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=3,4,5,5,4,3
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=normal_right
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=6,7,8,8,7,6
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_up
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=9,10,11,11,10,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_left
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=12,13,14,14,13,12
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_right
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=15,16,17,17,26,15
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=39
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=6
|
||||
speed=0.1
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
[/animation]
|
||||
@@ -3,133 +3,133 @@ frame_height=32
|
||||
|
||||
[animation]
|
||||
name=walk
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2,3
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand
|
||||
speed=10
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=4,5,6,7
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=8,9,10,11
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=12,13,14,15
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=20
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=21
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=22
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=23,24,25,26
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=27,28,29,30
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=31,32,33,34
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=35
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=36
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=37
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=rolling
|
||||
speed=10
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=38,39,40,41
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=celebration
|
||||
speed=10
|
||||
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]
|
||||
|
||||
[animation]
|
||||
name=dizzy
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=47,48,49,50,51,52,53
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=recover
|
||||
speed=3
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=54,54,54,54,55,56,57,58,58,58,59,60,61,58,59,60,61,58,59,60,61,62,62,62,62
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hello
|
||||
speed=3
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=63,64,65,66,67,68,69,70,71,72,73,73,73,73,73,73,73,73,73,73,73,73,73,74,75,76,77,78,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=44
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2,3
|
||||
[/animation]
|
||||
@@ -3,14 +3,14 @@ frame_height=32
|
||||
|
||||
[animation]
|
||||
name=fly
|
||||
speed=2
|
||||
speed=0.0333
|
||||
loop=0
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hit
|
||||
speed=2
|
||||
speed=0.0333
|
||||
loop=0
|
||||
frames=2,3
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6
|
||||
[/animation]
|
||||
79
deltatime_cleanup_plan.md
Normal file
79
deltatime_cleanup_plan.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Plan de Limpieza Post-Migración DeltaTime
|
||||
|
||||
## Estado Actual
|
||||
✅ Migración básica completada: bullet.cpp, item.cpp, moving_sprite.cpp, game_logo.cpp
|
||||
✅ Magic numbers convertidos a constantes en game_logo.cpp
|
||||
|
||||
## Tareas Pendientes
|
||||
|
||||
### 1. Eliminar Contadores Frame-Based
|
||||
- [ ] Buscar todos los contadores que usen lógica frame-based
|
||||
- [ ] Convertir a timers basados en deltaTime
|
||||
- [ ] Eliminar variables como `counter_`, `frame_counter_`, etc.
|
||||
- [ ] Patrón: `if (counter-- <= 0)` → `if (timer >= DURATION_MS)`
|
||||
- [ ] **IMPORTANTE**: Todos los contadores han de ser crecientes, de cero hasta llegar a la constante que define su tope
|
||||
|
||||
### 2. Revisar Inicializaciones de Aceleraciones MovingSprite
|
||||
- [ ] Buscar todas las llamadas a `setAccelX()`, `setAccelY()`
|
||||
- [ ] Buscar asignaciones directas a `ax_`, `ay_`
|
||||
- [ ] Convertir de `pixels/frame²` a `pixels/ms²`
|
||||
- [ ] Factor de conversión: `valor_original / (16.67)²`
|
||||
|
||||
### 3. Problema Detectado: Demo - Creación Incorrecta de Globos
|
||||
- [ ] Investigar cómo se crean los globos en modo demo
|
||||
- [ ] Verificar si usan timing frame-based obsoleto
|
||||
- [ ] Corregir la lógica de creación para deltaTime
|
||||
|
||||
### 4. Búsqueda de Patrones Problemáticos
|
||||
- [ ] Buscar `frameFactor` residual
|
||||
- [ ] Buscar `1000.0f / 60.0f` hardcodeado
|
||||
- [ ] Buscar `16.67f` hardcodeado
|
||||
- [ ] Buscar comentarios con "frame" o "60fps"
|
||||
- [ ] Localizar magic numbers y convertirlos a constantes con nombres descriptivos
|
||||
- [ ] **IMPORTANTE**: Modificar speed en ficheros .ani - está en frames, hay que pasarlo a milisegundos (multiplicar speed por 1000/60 = 16.67)
|
||||
- [ ] **SmartSprite**: Revisar inicialización de SmartSprites en el código - cambiar setFinishedCounter() a setFinishedDelay() y convertir valores de frames a milisegundos
|
||||
|
||||
### 5. Cambio de Unidades de Tiempo en sections/*
|
||||
- [ ] Cambiar el cálculo de deltatime en source/sections/* para que devuelva segundos (float) en lugar de milisegundos
|
||||
- [ ] Cambiar velocidades de pixeles/ms a pixeles/segundos para evitar valores absurdamente pequeños
|
||||
- [ ] Cambiar aceleraciones de pixeles/ms² a pixeles/segundos²
|
||||
- [ ] Actualizar todas las constantes de tiempo en archivos de sections
|
||||
|
||||
### 6. Archivos Prioritarios a Revisar
|
||||
- [ ] **player.cpp** - puede tener aceleraciones
|
||||
- [ ] **balloon.cpp** - contadores de estado
|
||||
- [ ] **stage.cpp** - timers de nivel
|
||||
- [ ] **credits.cpp** - efectos de texto
|
||||
- [ ] **tabe.cpp** - movimiento del protagonista
|
||||
- [ ] **sections/*.cpp** - transiciones y efectos
|
||||
|
||||
### 7. Validación Final
|
||||
- [ ] Compilar sin warnings
|
||||
- [ ] Probar gameplay normal
|
||||
- [ ] Probar modo demo
|
||||
- [ ] Verificar que no hay saltos de velocidad
|
||||
- [ ] Confirmar que el timing es consistente en diferentes framerates
|
||||
|
||||
## Comandos Útiles de Búsqueda
|
||||
```bash
|
||||
# Buscar contadores frame-based
|
||||
rg "counter.*--|\+\+.*counter|counter.*\+\+|--.*counter"
|
||||
|
||||
# Buscar inicializaciones de aceleración
|
||||
rg "setAccel|\.ax.*=|\.ay.*="
|
||||
|
||||
# Buscar hardcoded framerates
|
||||
rg "60\.0|16\.67|1000\.0.*60"
|
||||
```
|
||||
|
||||
## DECISIÓN IMPORTANTE: TODO EL CÓDIGO USA SEGUNDOS
|
||||
- **CAMBIO DE PLAN**: Todo el código del juego debe usar deltaTime en segundos (float)
|
||||
- **NO** debe haber soporte para frames, milisegundos y segundos simultáneamente
|
||||
- **SOLO SEGUNDOS** en todo el codebase
|
||||
- Velocidades en `pixels/segundos`, aceleraciones en `pixels/segundos²`
|
||||
- Todos los contadores deben ser crecientes (0 → constante_tope)
|
||||
- Eliminar todos los métodos duales (updateS, setSpeedS, etc.) - solo una versión
|
||||
- Convertir completamente: path_sprite.cpp, writer.cpp, tiled_bg.cpp, etc.
|
||||
- Documentar las conversiones en comentarios
|
||||
- Crear constantes para valores repetidos
|
||||
- Evitar números mágicos
|
||||
136
game_cpp_repair_plan.md
Normal file
136
game_cpp_repair_plan.md
Normal file
@@ -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<float>(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
|
||||
@@ -92,15 +92,12 @@ void AnimatedSprite::animate(float deltaTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convertir speed (frames) a tiempo: speed frames = speed * (1000ms/60fps) milisegundos
|
||||
float frameTime = static_cast<float>(animations_[current_animation_].speed) * (1000.0f / 60.0f);
|
||||
|
||||
// Acumular tiempo transcurrido
|
||||
animations_[current_animation_].time_accumulator += deltaTime;
|
||||
|
||||
// Verificar si es momento de cambiar frame
|
||||
if (animations_[current_animation_].time_accumulator >= frameTime) {
|
||||
animations_[current_animation_].time_accumulator -= frameTime;
|
||||
if (animations_[current_animation_].time_accumulator >= animations_[current_animation_].speed) {
|
||||
animations_[current_animation_].time_accumulator -= animations_[current_animation_].speed;
|
||||
animations_[current_animation_].current_frame++;
|
||||
|
||||
// Si alcanza el final de la animación
|
||||
@@ -132,12 +129,10 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
|
||||
current_animation_ = NEW_ANIMATION;
|
||||
if (reset) {
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].time_accumulator = 0.0f;
|
||||
animations_[current_animation_].completed = false;
|
||||
} else {
|
||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||
}
|
||||
@@ -153,12 +148,10 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
|
||||
current_animation_ = NEW_ANIMATION;
|
||||
if (reset) {
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].time_accumulator = 0.0f;
|
||||
animations_[current_animation_].completed = false;
|
||||
} else {
|
||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||
}
|
||||
@@ -175,7 +168,6 @@ void AnimatedSprite::update(float deltaTime) {
|
||||
// Reinicia la animación
|
||||
void AnimatedSprite::resetAnimation() {
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].time_accumulator = 0.0f;
|
||||
animations_[current_animation_].completed = false;
|
||||
animations_[current_animation_].paused = false;
|
||||
@@ -202,6 +194,12 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer& so
|
||||
// Pone un valor por defecto
|
||||
setWidth(config.frame_width);
|
||||
setHeight(config.frame_height);
|
||||
|
||||
// Establece el primer frame inmediatamente si hay animaciones
|
||||
if (!animations_.empty()) {
|
||||
current_animation_ = 0;
|
||||
updateSpriteClip();
|
||||
}
|
||||
}
|
||||
|
||||
// Procesa una línea de configuración
|
||||
@@ -271,7 +269,7 @@ void AnimatedSprite::processAnimationParameter(const std::string& line, Animatio
|
||||
if (key == "name") {
|
||||
animation.name = value;
|
||||
} else if (key == "speed") {
|
||||
animation.speed = std::stoi(value);
|
||||
animation.speed = std::stof(value);
|
||||
} else if (key == "loop") {
|
||||
animation.loop = std::stoi(value);
|
||||
} else if (key == "frames") {
|
||||
@@ -298,7 +296,7 @@ void AnimatedSprite::parseFramesParameter(const std::string& frames_str, Animati
|
||||
}
|
||||
|
||||
// Establece la velocidad de la animación
|
||||
void AnimatedSprite::setAnimationSpeed(size_t value) {
|
||||
void AnimatedSprite::setAnimationSpeed(float value) {
|
||||
animations_[current_animation_].speed = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,15 +17,14 @@ class Texture;
|
||||
|
||||
// --- Estructuras ---
|
||||
struct Animation {
|
||||
static constexpr int DEFAULT_SPEED = 5;
|
||||
static constexpr float DEFAULT_SPEED = 80.0F;
|
||||
|
||||
std::string name; // Nombre de la animación
|
||||
std::vector<SDL_FRect> frames; // Frames que componen la animación
|
||||
int speed{DEFAULT_SPEED}; // Velocidad de reproducción (frame-based)
|
||||
float speed{DEFAULT_SPEED}; // Velocidad de reproducción (ms entre frames)
|
||||
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
|
||||
bool completed{false}; // Indica si la animación ha finalizado
|
||||
size_t current_frame{0}; // Frame actual en reproducción
|
||||
int counter{0}; // Contador para la animación (frame-based)
|
||||
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based
|
||||
bool paused{false}; // La animación no avanza
|
||||
|
||||
@@ -62,8 +61,8 @@ class AnimatedSprite : public MovingSprite {
|
||||
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
|
||||
void setCurrentAnimation(int index = 0, bool reset = true); // Establece la animación por índice
|
||||
void resetAnimation(); // Reinicia la animación actual
|
||||
void setAnimationSpeed(size_t value); // Establece la velocidad de la animación
|
||||
auto getAnimationSpeed() const -> size_t { return animations_[current_animation_].speed; } // Obtiene la velocidad de la animación actual
|
||||
void setAnimationSpeed(float value); // Establece la velocidad de la animación
|
||||
auto getAnimationSpeed() const -> float { return animations_[current_animation_].speed; } // Obtiene la velocidad de la animación actual
|
||||
void animtionPause() { animations_[current_animation_].paused = true; } // Detiene la animación
|
||||
void animationResume() { animations_[current_animation_].paused = false; } // Reanuda la animación
|
||||
auto getCurrentAnimationFrame() const -> size_t { return animations_[current_animation_].current_frame; } // Obtiene el numero de frame de la animación actual
|
||||
|
||||
@@ -138,8 +138,12 @@ void Background::update(float delta_time) {
|
||||
// Actualiza las nubes
|
||||
updateClouds(delta_time);
|
||||
|
||||
// Calcula el frame de la hierba
|
||||
grass_sprite_->setSpriteClip(0, (10 * (counter_ / 20 % 2)), 320, 10);
|
||||
// Actualiza timer de hierba
|
||||
grass_timer_ += delta_time;
|
||||
|
||||
// Calcula el frame de la hierba (alterna cada GRASS_FRAME_DURATION ms)
|
||||
int grass_frame = static_cast<int>(grass_timer_ / GRASS_FRAME_DURATION) % 2;
|
||||
grass_sprite_->setSpriteClip(0, (10 * grass_frame), 320, 10);
|
||||
|
||||
// Calcula el valor de alpha
|
||||
alpha_ = std::max((255 - (int)(255 * transition_)), 0);
|
||||
@@ -148,9 +152,6 @@ void Background::update(float delta_time) {
|
||||
sun_sprite_->setPosition(sun_path_.at(sun_index_));
|
||||
moon_sprite_->setPosition(moon_path_.at(moon_index_));
|
||||
|
||||
// Incrementa el contador
|
||||
++counter_;
|
||||
|
||||
// Compone todos los elementos del fondo en la textura
|
||||
fillCanvas();
|
||||
}
|
||||
|
||||
@@ -107,7 +107,8 @@ class Background {
|
||||
float clouds_speed_ = 0; // Velocidad de las nubes
|
||||
float transition_ = 0; // Porcentaje de transición
|
||||
size_t gradient_number_ = 0; // Índice de fondo degradado
|
||||
size_t counter_ = 0; // Contador interno
|
||||
float grass_timer_ = 0.0f; // Timer para animación de hierba (ms)
|
||||
static constexpr float GRASS_FRAME_DURATION = 333.34f; // Duración por frame de hierba (20 frames * 16.67ms)
|
||||
size_t alpha_color_texture_ = 0; // Transparencia de atenuación
|
||||
size_t previous_alpha_color_texture_ = 0; // Transparencia anterior
|
||||
size_t sun_index_ = 0; // Índice del recorrido del sol
|
||||
|
||||
@@ -23,13 +23,13 @@ Balloon::Balloon(const Config& config)
|
||||
creation_counter_ini_(config.creation_counter),
|
||||
type_(config.type),
|
||||
size_(config.size),
|
||||
speed_(config.speed),
|
||||
game_tempo_(config.game_tempo),
|
||||
play_area_(config.play_area),
|
||||
sound_(config.sound) {
|
||||
switch (type_) {
|
||||
case Type::BALLOON: {
|
||||
vy_ = 0;
|
||||
max_vy_ = 3.0F;
|
||||
max_vy_ = 3.0F * 60.0F; // Convert from frames to seconds (180 pixels/s)
|
||||
|
||||
const int INDEX = static_cast<int>(size_);
|
||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||
@@ -65,12 +65,12 @@ Balloon::Balloon(const Config& config)
|
||||
power_ = score_ = menace_ = 0;
|
||||
|
||||
vy_ = 0;
|
||||
max_vy_ = 3.0F;
|
||||
max_vy_ = 3.0F * 60.0F; // Convert from frames to seconds (180 pixels/s)
|
||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
||||
|
||||
sprite_->setRotate(config.creation_counter <= 0);
|
||||
sprite_->setRotateAmount(vx_ > 0.0F ? 2.0 : -2.0);
|
||||
sprite_->setRotateAmount(vx_ > 0.0F ? 120.0 : -120.0); // Convert from 2 degrees/frame to 120 degrees/second
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -89,6 +89,12 @@ Balloon::Balloon(const Config& config)
|
||||
|
||||
// Establece la animación a usar
|
||||
setAnimation();
|
||||
|
||||
// Si no se está creando (creation_counter = 0), asegurar estado activo
|
||||
if (!being_created_) {
|
||||
start();
|
||||
setInvulnerable(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Centra el globo en la posición X
|
||||
@@ -147,9 +153,8 @@ void Balloon::move(float deltaTime) {
|
||||
}
|
||||
|
||||
void Balloon::handleHorizontalMovement(float deltaTime) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
x_ += vx_ * speed_ * frameFactor;
|
||||
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
|
||||
x_ += vx_ * game_tempo_ * deltaTime;
|
||||
|
||||
const int CLIP = 2;
|
||||
const float MIN_X = play_area_.x - CLIP;
|
||||
@@ -161,9 +166,8 @@ void Balloon::handleHorizontalMovement(float deltaTime) {
|
||||
}
|
||||
|
||||
void Balloon::handleVerticalMovement(float deltaTime) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
y_ += vy_ * speed_ * frameFactor;
|
||||
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
|
||||
y_ += vy_ * game_tempo_ * deltaTime;
|
||||
|
||||
if (shouldCheckTopCollision()) {
|
||||
handleTopCollision();
|
||||
@@ -219,15 +223,8 @@ void Balloon::handleBottomCollision() {
|
||||
}
|
||||
|
||||
void Balloon::applyGravity(float deltaTime) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
|
||||
travel_y_ += speed_ * frameFactor;
|
||||
|
||||
if (travel_y_ >= 1.0F) {
|
||||
travel_y_ -= 1.0F;
|
||||
vy_ += gravity_;
|
||||
}
|
||||
// DeltaTime en segundos: aceleración (pixels/s²) * tempo * tiempo (s)
|
||||
vy_ += gravity_ * game_tempo_ * deltaTime;
|
||||
}
|
||||
|
||||
void Balloon::playBouncingSound() {
|
||||
@@ -250,9 +247,8 @@ void Balloon::update(float deltaTime) {
|
||||
shiftSprite();
|
||||
shiftColliders();
|
||||
sprite_->update(deltaTime);
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
counter_ += frameFactor;
|
||||
// Contador interno con deltaTime en segundos
|
||||
counter_ += deltaTime;
|
||||
}
|
||||
|
||||
// Actualiza los estados del globo (time-based)
|
||||
@@ -264,17 +260,15 @@ void Balloon::updateState(float deltaTime) {
|
||||
setInvulnerable(true);
|
||||
|
||||
if (creation_counter_ > 0) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
|
||||
// Desplaza lentamente el globo hacia abajo y hacia un lado
|
||||
// Cada 10 frames (aproximadamente cada 166ms a 60fps)
|
||||
movement_accumulator_ += frameFactor;
|
||||
// Cada 10/60 segundos (equivalente a 10 frames a 60fps)
|
||||
movement_accumulator_ += deltaTime;
|
||||
|
||||
if (movement_accumulator_ >= 10.0f) {
|
||||
movement_accumulator_ -= 10.0f;
|
||||
constexpr float MOVEMENT_INTERVAL_S = 10.0f / 60.0f; // 10 frames = ~0.167s
|
||||
if (movement_accumulator_ >= MOVEMENT_INTERVAL_S) {
|
||||
movement_accumulator_ -= MOVEMENT_INTERVAL_S;
|
||||
y_++;
|
||||
x_ += vx_;
|
||||
x_ += vx_ / 60.0f; // Convierte de pixels/segundo a pixels/frame para movimiento discreto
|
||||
|
||||
// Comprueba no se salga por los laterales
|
||||
const int MIN_X = play_area_.x;
|
||||
@@ -282,11 +276,11 @@ void Balloon::updateState(float deltaTime) {
|
||||
|
||||
if (x_ < MIN_X || x_ > MAX_X) {
|
||||
// Corrige y cambia el sentido de la velocidad
|
||||
x_ -= vx_;
|
||||
x_ -= vx_ / 60.0f;
|
||||
vx_ = -vx_;
|
||||
}
|
||||
}
|
||||
creation_counter_ -= frameFactor;
|
||||
creation_counter_ -= deltaTime;
|
||||
if (creation_counter_ < 0) creation_counter_ = 0;
|
||||
}
|
||||
|
||||
@@ -321,11 +315,14 @@ void Balloon::setAnimation() {
|
||||
}
|
||||
|
||||
// Establece el frame de animación
|
||||
std::string chosen_animation;
|
||||
if (use_reversed_colors_) {
|
||||
sprite_->setCurrentAnimation(creating_animation);
|
||||
chosen_animation = creating_animation;
|
||||
} else {
|
||||
sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
|
||||
chosen_animation = isBeingCreated() ? creating_animation : normal_animation;
|
||||
}
|
||||
|
||||
sprite_->setCurrentAnimation(chosen_animation);
|
||||
}
|
||||
|
||||
// Detiene el globo
|
||||
|
||||
@@ -36,10 +36,12 @@ class Balloon {
|
||||
"balloon_pop2.wav",
|
||||
"balloon_pop3.wav"};
|
||||
|
||||
static constexpr float VELX_POSITIVE = 0.7F;
|
||||
static constexpr float VELX_NEGATIVE = -0.7F;
|
||||
// Velocidades horizontales en pixels/segundo (convertidas desde 0.7 pixels/frame a 60fps)
|
||||
static constexpr float VELX_POSITIVE = 0.7F * 60.0F; // 42 pixels/segundo
|
||||
static constexpr float VELX_NEGATIVE = -0.7F * 60.0F; // -42 pixels/segundo
|
||||
|
||||
static constexpr std::array<float, 5> SPEED = {0.60F, 0.70F, 0.80F, 0.90F, 1.00F};
|
||||
// Multiplicadores de tempo del juego (sin cambios, son puros multiplicadores)
|
||||
static constexpr std::array<float, 5> GAME_TEMPO = {0.60F, 0.70F, 0.80F, 0.90F, 1.00F};
|
||||
|
||||
static constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
|
||||
static constexpr int POWERBALL_COUNTER = 8;
|
||||
@@ -74,8 +76,8 @@ class Balloon {
|
||||
Type type = Type::BALLOON;
|
||||
Size size = Size::EXTRALARGE;
|
||||
float vel_x = VELX_POSITIVE;
|
||||
float speed = SPEED.at(0);
|
||||
Uint16 creation_counter = 0;
|
||||
float game_tempo = GAME_TEMPO.at(0);
|
||||
float creation_counter = 0.0f;
|
||||
SDL_FRect play_area = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
|
||||
std::shared_ptr<Texture> texture = nullptr;
|
||||
std::vector<std::string> animation;
|
||||
@@ -120,7 +122,7 @@ class Balloon {
|
||||
|
||||
// --- Setters ---
|
||||
void setVelY(float vel_y) { vy_ = vel_y; }
|
||||
void setSpeed(float speed) { speed_ = speed; }
|
||||
void setGameTempo(float tempo) { game_tempo_ = tempo; }
|
||||
void setInvulnerable(bool value) { invulnerable_ = value; }
|
||||
void setBouncingSound(bool value) { sound_.bouncing_enabled = value; }
|
||||
void setPoppingSound(bool value) { sound_.poping_enabled = value; }
|
||||
@@ -263,8 +265,7 @@ class Balloon {
|
||||
Size size_; // Tamaño de globo
|
||||
Uint8 menace_; // Amenaza que genera el globo
|
||||
Uint32 counter_ = 0; // Contador interno
|
||||
float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad
|
||||
float speed_; // Velocidad del globo
|
||||
float game_tempo_; // Multiplicador de tempo del juego
|
||||
float movement_accumulator_ = 0.0f; // Acumulador para movimiento durante creación (deltaTime)
|
||||
Uint8 power_; // Poder que alberga el globo
|
||||
SDL_FRect play_area_; // Zona de movimiento del globo
|
||||
|
||||
@@ -155,7 +155,7 @@ auto BalloonFormations::parseBalloonLine(const std::string& line, const std::map
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int creation_time = DEFAULT_CREATION_TIME + evaluateExpression(tokens.at(6), variables);
|
||||
float creation_time = CREATION_TIME + evaluateExpression(tokens.at(6), variables); // Base time + offset from formations.txt
|
||||
|
||||
return SpawnParams(x + offset, y, vel_x, type, size, creation_time);
|
||||
} catch (const std::exception&) {
|
||||
@@ -168,7 +168,7 @@ auto BalloonFormations::evaluateExpression(const std::string& expr, const std::m
|
||||
|
||||
// Si es un número directo
|
||||
if ((std::isdigit(trimmed_expr.at(0)) != 0) || (trimmed_expr.at(0) == '-' && trimmed_expr.length() > 1)) {
|
||||
return std::stoi(trimmed_expr);
|
||||
return std::stof(trimmed_expr);
|
||||
}
|
||||
|
||||
// Si es una variable simple
|
||||
@@ -205,7 +205,7 @@ auto BalloonFormations::evaluateSimpleExpression(const std::string& expr, const
|
||||
}
|
||||
|
||||
// Si no se encuentra operador, intentar como variable o número
|
||||
return variables.find(expr) != variables.end() ? variables.at(expr) : std::stoi(expr);
|
||||
return variables.find(expr) != variables.end() ? variables.at(expr) : std::stof(expr);
|
||||
}
|
||||
|
||||
auto BalloonFormations::trim(const std::string& str) -> std::string {
|
||||
@@ -235,10 +235,10 @@ void BalloonFormations::createFloaterVariants() {
|
||||
#ifdef _DEBUG
|
||||
void BalloonFormations::addTestFormation() {
|
||||
std::vector<SpawnParams> test_params = {
|
||||
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 200},
|
||||
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 200},
|
||||
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 200},
|
||||
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 200}};
|
||||
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 3.334f}}; // 200 frames ÷ 60fps = 3.334s
|
||||
|
||||
formations_.at(99) = Formation(test_params);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ class BalloonFormations {
|
||||
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
||||
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
|
||||
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
|
||||
Uint16 creation_counter = 0; // Temporizador para la creación del globo
|
||||
float creation_counter = 0.0f; // Temporizador para la creación del globo
|
||||
|
||||
// Constructor por defecto
|
||||
SpawnParams() = default;
|
||||
|
||||
// Constructor con parámetros
|
||||
SpawnParams(float x, float y, float vel_x, Balloon::Type type, Balloon::Size size, Uint16 creation_counter)
|
||||
SpawnParams(float x, float y, float vel_x, Balloon::Type type, Balloon::Size size, float creation_counter)
|
||||
: x(x),
|
||||
y(y),
|
||||
vel_x(vel_x),
|
||||
@@ -82,7 +82,8 @@ class BalloonFormations {
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr int BALLOON_SPAWN_HEIGHT = 208; // Altura desde el suelo en la que aparecen los globos
|
||||
static constexpr int DEFAULT_CREATION_TIME = 200; // Tiempo base de creación de los globos para las formaciones
|
||||
static constexpr float CREATION_TIME = 5.0f; // Tiempo base de creación de los globos en segundos (300 frames ÷ 60fps = 5.0s)
|
||||
static constexpr float DEFAULT_CREATION_TIME = 3.334f; // Tiempo base de creación de los globos en segundos (200 frames ÷ 60fps = 3.334s)
|
||||
|
||||
// --- Variables ---
|
||||
std::vector<Formation> formations_; // Vector con todas las formaciones disponibles
|
||||
|
||||
@@ -81,12 +81,12 @@ void BalloonManager::render() {
|
||||
|
||||
// Crea una formación de globos
|
||||
void BalloonManager::deployRandomFormation(int stage) {
|
||||
// Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última
|
||||
if (balloon_deploy_counter_ == 0) {
|
||||
// Solo despliega una formación enemiga si el timer ha llegado a cero
|
||||
if (balloon_deploy_counter_ <= 0.0f) {
|
||||
// En este punto se decide entre crear una powerball o una formación enemiga
|
||||
if ((rand() % 100 < 15) && (canPowerBallBeCreated())) {
|
||||
createPowerBall(); // Crea una powerball
|
||||
balloon_deploy_counter_ = 10; // Da un poco de margen para que se creen mas globos
|
||||
createPowerBall(); // Crea una powerball
|
||||
balloon_deploy_counter_ = POWERBALL_DEPLOY_DELAY; // Resetea con pequeño retraso
|
||||
} else {
|
||||
// Decrementa el contador de despliegues de globos necesarios para la siguiente PowerBall
|
||||
if (power_ball_counter_ > 0) {
|
||||
@@ -113,13 +113,13 @@ void BalloonManager::deployRandomFormation(int stage) {
|
||||
.type = balloon.type,
|
||||
.size = balloon.size,
|
||||
.vel_x = balloon.vel_x,
|
||||
.speed = balloon_speed_,
|
||||
.creation_counter = static_cast<Uint16>(creation_time_enabled_ ? balloon.creation_counter : 0)};
|
||||
.game_tempo = balloon_speed_,
|
||||
.creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0f};
|
||||
createBalloon(config);
|
||||
}
|
||||
|
||||
// Reinicia el contador para el próximo despliegue
|
||||
balloon_deploy_counter_ = DEFAULT_BALLOON_DEPLOY_COUNTER;
|
||||
// Reinicia el timer para el próximo despliegue
|
||||
balloon_deploy_counter_ = DEFAULT_BALLOON_DEPLOY_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ void BalloonManager::deployFormation(int formation_id) {
|
||||
.type = balloon.type,
|
||||
.size = balloon.size,
|
||||
.vel_x = balloon.vel_x,
|
||||
.speed = balloon_speed_,
|
||||
.game_tempo = balloon_speed_,
|
||||
.creation_counter = balloon.creation_counter};
|
||||
createBalloon(config);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ void BalloonManager::deployFormation(int formation_id, float y) {
|
||||
.type = balloon.type,
|
||||
.size = balloon.size,
|
||||
.vel_x = balloon.vel_x,
|
||||
.speed = balloon_speed_,
|
||||
.game_tempo = balloon_speed_,
|
||||
.creation_counter = balloon.creation_counter};
|
||||
createBalloon(config);
|
||||
}
|
||||
@@ -162,14 +162,10 @@ void BalloonManager::freeBalloons() {
|
||||
balloons_.erase(result.begin(), balloons_.end());
|
||||
}
|
||||
|
||||
// Actualiza la variable enemyDeployCounter (time-based)
|
||||
// Actualiza el timer de despliegue de globos (time-based)
|
||||
void BalloonManager::updateBalloonDeployCounter(float deltaTime) {
|
||||
if (balloon_deploy_counter_ > 0) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
balloon_deploy_counter_ -= frameFactor;
|
||||
if (balloon_deploy_counter_ < 0) balloon_deploy_counter_ = 0;
|
||||
}
|
||||
// DeltaTime en segundos - timer decrementa hasta llegar a cero
|
||||
balloon_deploy_counter_ -= deltaTime;
|
||||
}
|
||||
|
||||
// Indica si se puede crear una powerball
|
||||
@@ -214,14 +210,15 @@ void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon,
|
||||
.y = balloon->getPosY() + ((PARENT_HEIGHT - CHILD_HEIGHT) / 2),
|
||||
.size = static_cast<Balloon::Size>(static_cast<int>(balloon->getSize()) - 1),
|
||||
.vel_x = direction == "LEFT" ? Balloon::VELX_NEGATIVE : Balloon::VELX_POSITIVE,
|
||||
.speed = balloon_speed_,
|
||||
.game_tempo = balloon_speed_,
|
||||
.creation_counter = 0};
|
||||
|
||||
// Crea el globo
|
||||
auto b = createBalloon(config);
|
||||
|
||||
// Establece parametros
|
||||
b->setVelY(b->getType() == Balloon::Type::BALLOON ? -2.50F : Balloon::VELX_NEGATIVE * 2.0F);
|
||||
// Establece parametros (deltaTime en segundos - velocidades en pixels/segundo)
|
||||
constexpr float VEL_Y_BALLOON_PER_S = -150.0F; // -2.50 pixels/frame convertido a pixels/segundo (-2.50 * 60 = -150)
|
||||
b->setVelY(b->getType() == Balloon::Type::BALLOON ? VEL_Y_BALLOON_PER_S : Balloon::VELX_NEGATIVE * 2.0F);
|
||||
|
||||
// Herencia de estados
|
||||
if (balloon->isStopped()) { b->stop(); }
|
||||
@@ -248,7 +245,7 @@ void BalloonManager::createPowerBall() {
|
||||
.type = Balloon::Type::POWERBALL,
|
||||
.size = Balloon::Size::EXTRALARGE,
|
||||
.vel_x = VEL_X.at(LUCK),
|
||||
.speed = balloon_speed_,
|
||||
.game_tempo = balloon_speed_,
|
||||
.creation_counter = 0,
|
||||
.play_area = play_area_,
|
||||
.texture = balloon_textures_.at(4),
|
||||
@@ -270,7 +267,7 @@ void BalloonManager::createPowerBall() {
|
||||
void BalloonManager::setBalloonSpeed(float speed) {
|
||||
balloon_speed_ = speed;
|
||||
for (auto &balloon : balloons_) {
|
||||
balloon->setSpeed(speed);
|
||||
balloon->setGameTempo(speed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +280,7 @@ auto BalloonManager::popBalloon(const std::shared_ptr<Balloon> &balloon) -> int
|
||||
balloon->pop(true);
|
||||
score = destroyAllBalloons();
|
||||
power_ball_enabled_ = false;
|
||||
balloon_deploy_counter_ = 20;
|
||||
balloon_deploy_counter_ = BALLOON_POP_DELAY; // Resetea con retraso
|
||||
} else {
|
||||
score = balloon->getScore();
|
||||
if (balloon->getSize() != Balloon::Size::SMALL) {
|
||||
@@ -339,7 +336,7 @@ auto BalloonManager::destroyAllBalloons() -> int {
|
||||
score += destroyBalloon(balloon);
|
||||
}
|
||||
|
||||
balloon_deploy_counter_ = 300;
|
||||
balloon_deploy_counter_ = DEFAULT_BALLOON_DEPLOY_DELAY;
|
||||
Screen::get()->flash(Colors::FLASH, 3);
|
||||
Screen::get()->shake();
|
||||
|
||||
@@ -349,7 +346,9 @@ auto BalloonManager::destroyAllBalloons() -> int {
|
||||
// Detiene todos los globos
|
||||
void BalloonManager::stopAllBalloons() {
|
||||
for (auto &balloon : balloons_) {
|
||||
balloon->stop();
|
||||
if (!balloon->isBeingCreated()) {
|
||||
balloon->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,28 +28,28 @@ class BalloonManager {
|
||||
~BalloonManager() = default;
|
||||
|
||||
// --- Métodos principales ---
|
||||
void update(float deltaTime); // Actualiza el estado de los globos (time-based)
|
||||
void render(); // Renderiza los globos en pantalla
|
||||
void update(float deltaTime); // Actualiza el estado de los globos (time-based)
|
||||
void render(); // Renderiza los globos en pantalla
|
||||
|
||||
// --- Gestión de globos ---
|
||||
void freeBalloons(); // Libera globos que ya no sirven
|
||||
|
||||
// --- Creación de formaciones enemigas ---
|
||||
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
||||
void deployFormation(int formation_id); // Crea una formación específica
|
||||
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
||||
void deployFormation(int formation_id); // Crea una formación específica
|
||||
void deployFormation(int formation_id, float y); // Crea una formación específica con coordenadas
|
||||
|
||||
// --- Creación de globos ---
|
||||
auto createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
||||
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
||||
void createPowerBall(); // Crea una PowerBall
|
||||
void createTwoBigBalloons(); // Crea dos globos grandes
|
||||
auto createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
||||
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
||||
void createPowerBall(); // Crea una PowerBall
|
||||
void createTwoBigBalloons(); // Crea dos globos grandes
|
||||
|
||||
// --- Control de velocidad y despliegue ---
|
||||
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
|
||||
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }; // Establece la velocidad base
|
||||
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }; // Restablece la velocidad de los globos
|
||||
void updateBalloonDeployCounter(float deltaTime); // Actualiza el contador de despliegue (time-based)
|
||||
void updateBalloonDeployCounter(float deltaTime); // Actualiza el contador de despliegue (time-based)
|
||||
auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una PowerBall
|
||||
auto calculateScreenPower() -> int; // Calcula el poder de los globos en pantalla
|
||||
|
||||
@@ -82,7 +82,9 @@ class BalloonManager {
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static const int DEFAULT_BALLOON_DEPLOY_COUNTER = 300;
|
||||
static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0f; // 300 frames = 5 segundos
|
||||
static constexpr float POWERBALL_DEPLOY_DELAY = 0.167f; // 10 frames = 0.167 segundos
|
||||
static constexpr float BALLOON_POP_DELAY = 0.333f; // 20 frames = 0.333 segundos
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
Balloons balloons_; // Vector con los globos activos
|
||||
@@ -96,8 +98,8 @@ class BalloonManager {
|
||||
|
||||
// --- Variables de estado ---
|
||||
SDL_FRect play_area_ = param.game.play_area.rect;
|
||||
float balloon_speed_ = Balloon::SPEED.at(0);
|
||||
float default_balloon_speed_ = Balloon::SPEED.at(0);
|
||||
float balloon_speed_ = Balloon::GAME_TEMPO.at(0);
|
||||
float default_balloon_speed_ = Balloon::GAME_TEMPO.at(0);
|
||||
float balloon_deploy_counter_ = 0;
|
||||
int power_ball_counter_ = 0;
|
||||
int last_balloon_deploy_ = 0;
|
||||
|
||||
@@ -68,16 +68,14 @@ auto Bullet::update(float deltaTime) -> BulletMoveStatus {
|
||||
|
||||
// Implementación del movimiento usando BulletMoveStatus (time-based)
|
||||
auto Bullet::move(float deltaTime) -> BulletMoveStatus {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
// 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();
|
||||
return BulletMoveStatus::OUT;
|
||||
}
|
||||
|
||||
pos_y_ += VEL_Y * frameFactor;
|
||||
pos_y_ += VEL_Y * deltaTime;
|
||||
if (pos_y_ < param.game.play_area.rect.y - HEIGHT) {
|
||||
disable();
|
||||
return BulletMoveStatus::OUT;
|
||||
|
||||
@@ -45,10 +45,10 @@ class Bullet {
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr float VEL_Y = -3.0F; // Velocidad vertical
|
||||
static constexpr float VEL_X_LEFT = -2.0F; // Velocidad izquierda
|
||||
static constexpr float VEL_X_RIGHT = 2.0F; // Velocidad derecha
|
||||
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<AnimatedSprite> sprite_; // Sprite con los gráficos
|
||||
|
||||
@@ -80,11 +80,12 @@ struct BalloonSettings {
|
||||
grav(g) {}
|
||||
};
|
||||
|
||||
// Valores para deltaTime en segundos: vel en pixels/s, grav en pixels/s² (aceleración)
|
||||
constexpr std::array<BalloonSettings, 4> SETTINGS = {{
|
||||
BalloonSettings(2.75F, 0.09F), // Globo 0
|
||||
BalloonSettings(3.70F, 0.10F), // Globo 1
|
||||
BalloonSettings(4.70F, 0.10F), // Globo 2
|
||||
BalloonSettings(5.45F, 0.10F) // Globo 3
|
||||
BalloonSettings(165.0F, 320.0F), // Globo 0: vel=165 pixels/s, grav=320 pixels/s²
|
||||
BalloonSettings(222.0F, 360.0F), // Globo 1: vel=222 pixels/s, grav=360 pixels/s²
|
||||
BalloonSettings(282.0F, 360.0F), // Globo 2: vel=282 pixels/s, grav=360 pixels/s²
|
||||
BalloonSettings(327.0F, 360.0F) // Globo 3: vel=327 pixels/s, grav=360 pixels/s²
|
||||
}};
|
||||
|
||||
constexpr std::array<const char*, 4> COLORS = {
|
||||
|
||||
@@ -45,7 +45,7 @@ void GameLogo::init() {
|
||||
arcade_edition_status_ = Status::DISABLED;
|
||||
shake_.init(1, 2, 8, XP);
|
||||
zoom_ = 3.0F * ZOOM_FACTOR;
|
||||
post_finished_time_accumulator_ = 0.0f;
|
||||
post_finished_timer_ = 0.0f;
|
||||
|
||||
// Inicializa el bitmap de 'Coffee'
|
||||
coffee_sprite_->setPosX(XP);
|
||||
@@ -53,44 +53,44 @@ void GameLogo::init() {
|
||||
coffee_sprite_->setWidth(coffee_texture_->getWidth());
|
||||
coffee_sprite_->setHeight(coffee_texture_->getHeight());
|
||||
coffee_sprite_->setVelX(0.0F);
|
||||
coffee_sprite_->setVelY(2.5F);
|
||||
coffee_sprite_->setVelY(COFFEE_VEL_Y);
|
||||
coffee_sprite_->setAccelX(0.0F);
|
||||
coffee_sprite_->setAccelY(0.1F);
|
||||
coffee_sprite_->setAccelY(COFFEE_ACCEL_Y);
|
||||
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
|
||||
coffee_sprite_->setEnabled(true);
|
||||
coffee_sprite_->setFinishedCounter(0);
|
||||
coffee_sprite_->setFinishedDelay(0.0f);
|
||||
coffee_sprite_->setDestX(XP);
|
||||
coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight());
|
||||
|
||||
// Inicializa el bitmap de 'Crisis'
|
||||
crisis_sprite_->setPosX(XP + 15);
|
||||
crisis_sprite_->setPosX(XP + CRISIS_OFFSET_X);
|
||||
crisis_sprite_->setPosY(y_ + DESP);
|
||||
crisis_sprite_->setWidth(crisis_texture_->getWidth());
|
||||
crisis_sprite_->setHeight(crisis_texture_->getHeight());
|
||||
crisis_sprite_->setVelX(0.0F);
|
||||
crisis_sprite_->setVelY(-2.5F);
|
||||
crisis_sprite_->setVelY(CRISIS_VEL_Y);
|
||||
crisis_sprite_->setAccelX(0.0F);
|
||||
crisis_sprite_->setAccelY(-0.1F);
|
||||
crisis_sprite_->setAccelY(CRISIS_ACCEL_Y);
|
||||
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
|
||||
crisis_sprite_->setEnabled(true);
|
||||
crisis_sprite_->setFinishedCounter(0);
|
||||
crisis_sprite_->setDestX(XP + 15);
|
||||
crisis_sprite_->setFinishedDelay(0.0f);
|
||||
crisis_sprite_->setDestX(XP + CRISIS_OFFSET_X);
|
||||
crisis_sprite_->setDestY(y_);
|
||||
|
||||
// Inicializa el bitmap de 'DustRight'
|
||||
dust_right_sprite_->resetAnimation();
|
||||
dust_right_sprite_->setPosX(coffee_sprite_->getPosX() + coffee_sprite_->getWidth());
|
||||
dust_right_sprite_->setPosY(y_);
|
||||
dust_right_sprite_->setWidth(16);
|
||||
dust_right_sprite_->setHeight(16);
|
||||
dust_right_sprite_->setWidth(DUST_SIZE);
|
||||
dust_right_sprite_->setHeight(DUST_SIZE);
|
||||
dust_right_sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
||||
|
||||
// Inicializa el bitmap de 'DustLeft'
|
||||
dust_left_sprite_->resetAnimation();
|
||||
dust_left_sprite_->setPosX(coffee_sprite_->getPosX() - 16);
|
||||
dust_left_sprite_->setPosX(coffee_sprite_->getPosX() - DUST_SIZE);
|
||||
dust_left_sprite_->setPosY(y_);
|
||||
dust_left_sprite_->setWidth(16);
|
||||
dust_left_sprite_->setHeight(16);
|
||||
dust_left_sprite_->setWidth(DUST_SIZE);
|
||||
dust_left_sprite_->setHeight(DUST_SIZE);
|
||||
|
||||
// Inicializa el bitmap de 'Arcade Edition'
|
||||
arcade_edition_sprite_->setZoom(zoom_);
|
||||
@@ -174,8 +174,8 @@ void GameLogo::handleCoffeeCrisisFinished(float deltaTime) {
|
||||
}
|
||||
|
||||
void GameLogo::handleArcadeEditionMoving(float deltaTime) {
|
||||
// Convertir 0.1F * ZOOM_FACTOR por frame a por milisegundo (asumiendo 60fps)
|
||||
zoom_ -= (0.1F * ZOOM_FACTOR) * deltaTime / (1000.0F / 60.0F);
|
||||
// DeltaTime en segundos: decremento por segundo
|
||||
zoom_ -= (ZOOM_DECREMENT_PER_S * ZOOM_FACTOR) * deltaTime;
|
||||
arcade_edition_sprite_->setZoom(zoom_);
|
||||
|
||||
if (zoom_ <= 1.0F) {
|
||||
@@ -192,40 +192,24 @@ void GameLogo::handleArcadeEditionShaking(float deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite) {
|
||||
if (shake_.counter > 0) {
|
||||
shake_.counter--;
|
||||
} else {
|
||||
shake_.counter = shake_.delay;
|
||||
const auto DISPLACEMENT = calculateShakeDisplacement();
|
||||
primary_sprite->setPosX(shake_.origin + DISPLACEMENT);
|
||||
if (secondary_sprite != nullptr) {
|
||||
secondary_sprite->setPosX(shake_.origin + DISPLACEMENT + 15);
|
||||
}
|
||||
shake_.remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime) {
|
||||
// Convertir delay (frames) a tiempo: delay frames = delay * (1000ms/60fps)
|
||||
float delayTime = static_cast<float>(shake_.delay) * (1000.0f / 60.0f);
|
||||
|
||||
shake_.time_accumulator += deltaTime;
|
||||
|
||||
if (shake_.time_accumulator >= delayTime) {
|
||||
shake_.time_accumulator -= delayTime;
|
||||
if (shake_.time_accumulator >= SHAKE_DELAY_S) {
|
||||
shake_.time_accumulator -= SHAKE_DELAY_S;
|
||||
const auto DISPLACEMENT = calculateShakeDisplacement();
|
||||
primary_sprite->setPosX(shake_.origin + DISPLACEMENT);
|
||||
if (secondary_sprite != nullptr) {
|
||||
secondary_sprite->setPosX(shake_.origin + DISPLACEMENT + 15);
|
||||
secondary_sprite->setPosX(shake_.origin + DISPLACEMENT + CRISIS_OFFSET_X);
|
||||
}
|
||||
shake_.remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
void GameLogo::processArcadeEditionShake(float deltaTime) {
|
||||
// Convertir delay (frames) a tiempo: delay frames = delay * (1000ms/60fps)
|
||||
float delayTime = static_cast<float>(shake_.delay) * (1000.0f / 60.0f);
|
||||
// Delay fijo en segundos (shake_.delay era frames, ahora usamos constante)
|
||||
float delayTime = SHAKE_DELAY_S;
|
||||
|
||||
shake_.time_accumulator += deltaTime;
|
||||
|
||||
@@ -243,7 +227,7 @@ auto GameLogo::calculateShakeDisplacement() const -> int {
|
||||
|
||||
void GameLogo::finishCoffeeCrisisShaking() {
|
||||
coffee_sprite_->setPosX(shake_.origin);
|
||||
crisis_sprite_->setPosX(shake_.origin + 15);
|
||||
crisis_sprite_->setPosX(shake_.origin + CRISIS_OFFSET_X);
|
||||
coffee_crisis_status_ = Status::FINISHED;
|
||||
arcade_edition_status_ = Status::MOVING;
|
||||
}
|
||||
@@ -269,18 +253,9 @@ void GameLogo::updateDustSprites(float deltaTime) {
|
||||
|
||||
void GameLogo::updatePostFinishedCounter(float deltaTime) {
|
||||
if (coffee_crisis_status_ == Status::FINISHED &&
|
||||
arcade_edition_status_ == Status::FINISHED &&
|
||||
post_finished_counter_ > 0) {
|
||||
|
||||
// Convertir 1 frame a tiempo: 1 frame = 1000ms/60fps = 16.67ms
|
||||
float frameTime = 1000.0f / 60.0f;
|
||||
|
||||
post_finished_time_accumulator_ += deltaTime;
|
||||
|
||||
if (post_finished_time_accumulator_ >= frameTime) {
|
||||
post_finished_time_accumulator_ -= frameTime;
|
||||
--post_finished_counter_;
|
||||
}
|
||||
arcade_edition_status_ == Status::FINISHED) {
|
||||
|
||||
post_finished_timer_ += deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +267,7 @@ void GameLogo::enable() {
|
||||
|
||||
// Indica si ha terminado la animación
|
||||
auto GameLogo::hasFinished() const -> bool {
|
||||
return post_finished_counter_ == 0;
|
||||
return post_finished_timer_ >= post_finished_delay_s_;
|
||||
}
|
||||
|
||||
// Calcula el desplazamiento vertical inicial
|
||||
|
||||
@@ -11,6 +11,17 @@ class Texture;
|
||||
// --- Clase GameLogo: gestor del logo del juego ---
|
||||
class GameLogo {
|
||||
public:
|
||||
// --- Constantes ---
|
||||
static constexpr float COFFEE_VEL_Y = 0.15F * 1000.0F; // Velocidad Y de coffee sprite (pixels/s) - 0.15F * 1000 = 150 pixels/s
|
||||
static constexpr float COFFEE_ACCEL_Y = 0.00036F * 1000000.0F; // Aceleración Y de coffee sprite (pixels/s²) - 0.00036F * 1000000 = 360 pixels/s²
|
||||
static constexpr float CRISIS_VEL_Y = -0.15F * 1000.0F; // Velocidad Y de crisis sprite (pixels/s) - -0.15F * 1000 = -150 pixels/s
|
||||
static constexpr float CRISIS_ACCEL_Y = -0.00036F * 1000000.0F; // Aceleración Y de crisis sprite (pixels/s²) - -0.00036F * 1000000 = -360 pixels/s²
|
||||
static constexpr int CRISIS_OFFSET_X = 15; // Desplazamiento X de crisis sprite
|
||||
static constexpr int DUST_SIZE = 16; // Tamaño de dust sprites
|
||||
static constexpr float ZOOM_DECREMENT_PER_S = 0.006F * 1000.0F; // Decremento de zoom por segundo (0.006F * 1000 = 6.0F per second)
|
||||
static constexpr float SHAKE_DELAY_S = 33.34F / 1000.0F; // Delay de shake en segundos (33.34ms / 1000 = 0.03334s)
|
||||
static constexpr float POST_FINISHED_FRAME_TIME_S = 16.67F / 1000.0F; // Tiempo entre decrementos del counter (16.67ms / 1000 = 0.01667s)
|
||||
|
||||
// --- Constructores y destructor ---
|
||||
GameLogo(int x, int y);
|
||||
~GameLogo() = default;
|
||||
@@ -81,8 +92,8 @@ class GameLogo {
|
||||
float x_; // Posición X del logo
|
||||
float y_; // Posición Y del logo
|
||||
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
|
||||
int post_finished_counter_ = 1; // Contador final tras animaciones (frame-based)
|
||||
float post_finished_time_accumulator_ = 0.0f; // Acumulador de tiempo para post_finished_counter
|
||||
float post_finished_delay_s_ = POST_FINISHED_FRAME_TIME_S; // Retraso final tras animaciones (s)
|
||||
float post_finished_timer_ = 0.0f; // Timer acumulado para retraso final (s)
|
||||
|
||||
// --- Inicialización ---
|
||||
void init(); // Inicializa las variables
|
||||
|
||||
@@ -19,9 +19,9 @@ Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::sha
|
||||
height_ = COFFEE_MACHINE_HEIGHT;
|
||||
pos_x_ = getCoffeeMachineSpawn(x, width_, play_area_.w);
|
||||
pos_y_ = y;
|
||||
vel_x_ = ((rand() % 3) - 1) * 0.5F;
|
||||
vel_y_ = -0.1F;
|
||||
accel_y_ = 0.1F;
|
||||
vel_x_ = ((rand() % 3) - 1) * COFFEE_MACHINE_VEL_X_FACTOR;
|
||||
vel_y_ = COFFEE_MACHINE_VEL_Y;
|
||||
accel_y_ = COFFEE_MACHINE_ACCEL_Y;
|
||||
collider_.r = 10;
|
||||
break;
|
||||
}
|
||||
@@ -34,13 +34,13 @@ Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::sha
|
||||
const int direction = rand() % 6;
|
||||
if (direction < 3) {
|
||||
// Velocidades negativas: -1.0, -0.66, -0.33
|
||||
vel_x_ = -1.0F + (direction * 0.33F);
|
||||
vel_x_ = -ITEM_VEL_X_BASE + (direction * ITEM_VEL_X_STEP);
|
||||
} else {
|
||||
// Velocidades positivas: 0.33, 0.66, 1.0
|
||||
vel_x_ = 0.33F + ((direction - 3) * 0.33F);
|
||||
vel_x_ = ITEM_VEL_X_STEP + ((direction - 3) * ITEM_VEL_X_STEP);
|
||||
}
|
||||
vel_y_ = -4.0F;
|
||||
accel_y_ = 0.2F;
|
||||
vel_y_ = ITEM_VEL_Y;
|
||||
accel_y_ = ITEM_ACCEL_Y;
|
||||
collider_.r = width_ / 2;
|
||||
break;
|
||||
}
|
||||
@@ -67,16 +67,16 @@ void Item::alignTo(int x) {
|
||||
|
||||
void Item::render() {
|
||||
if (enabled_) {
|
||||
// Muestra normalmente hasta los últimos ~3.3 segundos (200 frames)
|
||||
constexpr float BLINK_START_MS = LIFETIME_DURATION_MS - (200.0f * (1000.0f / 60.0f));
|
||||
// Muestra normalmente hasta los últimos ~3.3 segundos
|
||||
constexpr float BLINK_START_S = LIFETIME_DURATION_S - 3.33f;
|
||||
|
||||
if (lifetime_timer_ < BLINK_START_MS) {
|
||||
if (lifetime_timer_ < BLINK_START_S) {
|
||||
sprite_->render();
|
||||
} else {
|
||||
// Efecto de parpadeo en los últimos segundos (cada ~333ms o 20 frames)
|
||||
constexpr float BLINK_INTERVAL_MS = 20.0f * (1000.0f / 60.0f);
|
||||
const float phase = fmod(lifetime_timer_, BLINK_INTERVAL_MS);
|
||||
const float half_interval = BLINK_INTERVAL_MS / 2.0f;
|
||||
// Efecto de parpadeo en los últimos segundos (cada ~0.33 segundos)
|
||||
constexpr float BLINK_INTERVAL_S = 0.33f;
|
||||
const float phase = fmod(lifetime_timer_, BLINK_INTERVAL_S);
|
||||
const float half_interval = BLINK_INTERVAL_S / 2.0f;
|
||||
|
||||
if (phase < half_interval) {
|
||||
sprite_->render();
|
||||
@@ -86,17 +86,15 @@ void Item::render() {
|
||||
}
|
||||
|
||||
void Item::move(float deltaTime) {
|
||||
// Convertir deltaTime a factor de frame para compatibilidad (asumiendo 60fps)
|
||||
const float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
floor_collision_ = false;
|
||||
|
||||
// Calcula la nueva posición (time-based)
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
pos_y_ += vel_y_ * frameFactor;
|
||||
// Calcula la nueva posición usando deltaTime (velocidad en pixels/segundo)
|
||||
pos_x_ += vel_x_ * deltaTime;
|
||||
pos_y_ += vel_y_ * deltaTime;
|
||||
|
||||
// Aplica las aceleraciones a la velocidad (time-based)
|
||||
vel_x_ += accel_x_ * frameFactor;
|
||||
vel_y_ += accel_y_ * frameFactor;
|
||||
// Aplica las aceleraciones a la velocidad usando deltaTime (aceleración en pixels/segundo²)
|
||||
vel_x_ += accel_x_ * deltaTime;
|
||||
vel_y_ += accel_y_ * deltaTime;
|
||||
|
||||
// Comprueba los laterales de la zona de juego
|
||||
const float MIN_X = param.game.play_area.rect.x;
|
||||
@@ -126,24 +124,24 @@ void Item::move(float deltaTime) {
|
||||
case ItemType::COFFEE_MACHINE:
|
||||
// La máquina de café es mas pesada y tiene una fisica diferente, ademas hace ruido
|
||||
floor_collision_ = true;
|
||||
if (vel_y_ < 1.0F) {
|
||||
if (std::abs(vel_y_) < BOUNCE_VEL_THRESHOLD) {
|
||||
// Si la velocidad vertical es baja, detiene el objeto
|
||||
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
||||
} else {
|
||||
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
||||
vel_y_ *= -0.20F;
|
||||
vel_x_ *= 0.75F;
|
||||
vel_y_ *= COFFEE_BOUNCE_DAMPING;
|
||||
vel_x_ *= HORIZONTAL_DAMPING;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Si no es una máquina de café
|
||||
if (vel_y_ < 1.0F) {
|
||||
if (std::abs(vel_y_) < BOUNCE_VEL_THRESHOLD) {
|
||||
// Si la velocidad vertical es baja, detiene el objeto
|
||||
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
||||
} else {
|
||||
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
||||
vel_y_ *= -0.5F;
|
||||
vel_x_ *= 0.75F;
|
||||
vel_y_ *= ITEM_BOUNCE_DAMPING;
|
||||
vel_x_ *= HORIZONTAL_DAMPING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -164,7 +162,7 @@ void Item::update(float deltaTime) {
|
||||
|
||||
void Item::updateTimeToLive(float deltaTime) {
|
||||
lifetime_timer_ += deltaTime;
|
||||
if (lifetime_timer_ >= LIFETIME_DURATION_MS) {
|
||||
if (lifetime_timer_ >= LIFETIME_DURATION_S) {
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,24 @@ class Item {
|
||||
// --- Constantes ---
|
||||
static constexpr int COFFEE_MACHINE_WIDTH = 30; // Anchura de la máquina de café
|
||||
static constexpr int COFFEE_MACHINE_HEIGHT = 39; // Altura de la máquina de café
|
||||
static constexpr float LIFETIME_DURATION_MS = 10000.0f; // Duración de vida del ítem (600 frames a 60fps)
|
||||
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 = 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 = 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)
|
||||
static constexpr float COFFEE_BOUNCE_DAMPING = -0.20F; // Factor de rebote Y para máquina de café
|
||||
static constexpr float ITEM_BOUNCE_DAMPING = -0.5F; // Factor de rebote Y para items normales
|
||||
static constexpr float HORIZONTAL_DAMPING = 0.75F; // Factor de amortiguación horizontal
|
||||
|
||||
// --- Constructor y destructor ---
|
||||
Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation); // Constructor principal
|
||||
@@ -67,7 +84,7 @@ class Item {
|
||||
float accel_y_; // Aceleración en el eje Y
|
||||
int width_; // Ancho del objeto
|
||||
int height_; // Alto del objeto
|
||||
float lifetime_timer_ = 0.0f; // Acumulador de tiempo de vida del ítem (milisegundos)
|
||||
float lifetime_timer_ = 0.0f; // Acumulador de tiempo de vida del ítem (segundos)
|
||||
bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
|
||||
bool enabled_ = true; // Indica si el objeto está habilitado
|
||||
|
||||
|
||||
@@ -55,14 +55,13 @@ void MovingSprite::stop() {
|
||||
|
||||
// Mueve el sprite (time-based)
|
||||
void MovingSprite::move(float deltaTime) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
|
||||
x_ += vx_ * frameFactor;
|
||||
y_ += vy_ * frameFactor;
|
||||
// DeltaTime puro: velocidad (pixels/ms) * tiempo (ms)
|
||||
x_ += vx_ * deltaTime;
|
||||
y_ += vy_ * deltaTime;
|
||||
|
||||
vx_ += ax_ * frameFactor;
|
||||
vy_ += ay_ * frameFactor;
|
||||
// Aceleración (pixels/ms²) * tiempo (ms)
|
||||
vx_ += ax_ * deltaTime;
|
||||
vy_ += ay_ * deltaTime;
|
||||
|
||||
pos_.x = static_cast<int>(x_);
|
||||
pos_.y = static_cast<int>(y_);
|
||||
@@ -82,16 +81,13 @@ void MovingSprite::render() {
|
||||
// Establece la rotacion (time-based)
|
||||
void MovingSprite::rotate(float deltaTime) {
|
||||
if (rotate_.enabled) {
|
||||
// Convertir speed (frames) a tiempo: speed frames = speed * (1000ms/60fps) milisegundos
|
||||
float rotationFrameTime = static_cast<float>(rotate_.speed) * (1000.0f / 60.0f);
|
||||
rotate_.angle += rotate_.amount * (deltaTime / rotationFrameTime);
|
||||
rotate_.angle += rotate_.amount * deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Activa o desactiva el efecto de rotación
|
||||
void MovingSprite::setRotate(bool enable) {
|
||||
rotate_.enabled = enable;
|
||||
rotate_.counter = 0;
|
||||
}
|
||||
|
||||
// Establece la posición y_ el tamaño del objeto
|
||||
|
||||
@@ -15,7 +15,6 @@ class MovingSprite : public Sprite {
|
||||
// --- Estructuras ---
|
||||
struct Rotate {
|
||||
bool enabled{false}; // Indica si ha de rotar
|
||||
int counter{0}; // Contador
|
||||
int speed{1}; // Velocidad de giro
|
||||
double angle{0.0}; // Ángulo para dibujarlo
|
||||
float amount{0.0F}; // Cantidad de grados a girar en cada iteración
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include <functional> // Para function
|
||||
#include <utility> // Para move
|
||||
|
||||
// Constructor para paths por puntos (compatibilidad)
|
||||
Path::Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
|
||||
// Constructor para paths por puntos (convertido a segundos)
|
||||
Path::Path(const std::vector<SDL_FPoint> &spots_init, float waiting_time_s_init)
|
||||
: spots(spots_init), is_point_path(true) {
|
||||
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||
waiting_time_ms = static_cast<float>(waiting_counter_init) * FRAME_TIME_MS;
|
||||
waiting_time_s = waiting_time_s_init;
|
||||
}
|
||||
|
||||
// Devuelve un vector con los puntos que conforman la ruta
|
||||
@@ -39,12 +38,6 @@ auto createPath(float start, float end, PathType type, float fixed_pos, int step
|
||||
return v;
|
||||
}
|
||||
|
||||
// Actualiza la posición y comprueba si ha llegado a su destino (compatibilidad)
|
||||
void PathSprite::update() {
|
||||
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f; // 16.67ms por frame a 60 FPS
|
||||
update(FRAME_TIME_MS);
|
||||
}
|
||||
|
||||
// Actualiza la posición y comprueba si ha llegado a su destino
|
||||
void PathSprite::update(float delta_time) {
|
||||
if (enabled_ && !has_finished_) {
|
||||
@@ -90,20 +83,14 @@ void PathSprite::addPath(Path path, bool centered) {
|
||||
}
|
||||
}
|
||||
|
||||
// Añade un recorrido
|
||||
void PathSprite::addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easing_function, int waiting_counter) {
|
||||
// Convertir frames a milisegundos
|
||||
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||
float duration_ms = static_cast<float>(steps) * FRAME_TIME_MS;
|
||||
float waiting_ms = static_cast<float>(waiting_counter) * FRAME_TIME_MS;
|
||||
|
||||
paths_.emplace_back(static_cast<float>(start), static_cast<float>(end), type, static_cast<float>(fixed_pos),
|
||||
duration_ms, waiting_ms, easing_function);
|
||||
// Añade un recorrido generado (en segundos)
|
||||
void PathSprite::addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)> &easing_function, float waiting_time_s) {
|
||||
paths_.emplace_back(start, end, type, fixed_pos, duration_s, waiting_time_s, easing_function);
|
||||
}
|
||||
|
||||
// Añade un recorrido
|
||||
void PathSprite::addPath(const std::vector<SDL_FPoint> &spots, int waiting_counter) {
|
||||
paths_.emplace_back(spots, waiting_counter);
|
||||
// Añade un recorrido por puntos (en segundos)
|
||||
void PathSprite::addPath(const std::vector<SDL_FPoint> &spots, float waiting_time_s) {
|
||||
paths_.emplace_back(spots, waiting_time_s);
|
||||
}
|
||||
|
||||
// Habilita el objeto
|
||||
@@ -150,7 +137,7 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
|
||||
|
||||
if (path.on_destination) {
|
||||
path.waiting_elapsed += delta_time;
|
||||
if (path.waiting_elapsed >= path.waiting_time_ms) {
|
||||
if (path.waiting_elapsed >= path.waiting_time_s) {
|
||||
path.finished = true;
|
||||
}
|
||||
}
|
||||
@@ -160,7 +147,7 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
|
||||
path.elapsed_time += delta_time;
|
||||
|
||||
// Calcular progreso (0.0 a 1.0)
|
||||
float progress = path.elapsed_time / path.duration_ms;
|
||||
float progress = path.elapsed_time / path.duration_s;
|
||||
if (progress >= 1.0f) {
|
||||
progress = 1.0f;
|
||||
path.on_destination = true;
|
||||
@@ -183,7 +170,7 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
|
||||
} else {
|
||||
// Esperar en destino
|
||||
path.waiting_elapsed += delta_time;
|
||||
if (path.waiting_elapsed >= path.waiting_time_ms) {
|
||||
if (path.waiting_elapsed >= path.waiting_time_s) {
|
||||
path.finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ struct Path { // Define un re
|
||||
float end_pos; // Posición final
|
||||
PathType type; // Tipo de movimiento (horizontal/vertical)
|
||||
float fixed_pos; // Posición fija en el eje contrario
|
||||
float duration_ms; // Duración de la animación en milisegundos
|
||||
float waiting_time_ms; // Tiempo de espera una vez en el destino
|
||||
float duration_s; // Duración de la animación en segundos
|
||||
float waiting_time_s; // Tiempo de espera una vez en el destino
|
||||
std::function<double(double)> easing_function; // Función de easing
|
||||
float elapsed_time = 0.0f; // Tiempo transcurrido
|
||||
float waiting_elapsed = 0.0f; // Tiempo de espera transcurrido
|
||||
@@ -40,10 +40,10 @@ struct Path { // Define un re
|
||||
// Constructor para paths generados
|
||||
Path(float start, float end, PathType path_type, float fixed, float duration, float waiting, std::function<double(double)> easing)
|
||||
: start_pos(start), end_pos(end), type(path_type), fixed_pos(fixed),
|
||||
duration_ms(duration), waiting_time_ms(waiting), easing_function(std::move(easing)) {}
|
||||
duration_s(duration), waiting_time_s(waiting), easing_function(std::move(easing)) {}
|
||||
|
||||
// Constructor para paths por puntos (mantenemos compatibilidad)
|
||||
Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init);
|
||||
// Constructor para paths por puntos (convertido a segundos)
|
||||
Path(const std::vector<SDL_FPoint> &spots_init, float waiting_time_s_init);
|
||||
|
||||
// Variables para paths por puntos
|
||||
std::vector<SDL_FPoint> spots; // Solo para paths por puntos
|
||||
@@ -63,14 +63,13 @@ class PathSprite : public Sprite {
|
||||
~PathSprite() override = default;
|
||||
|
||||
// --- Métodos principales ---
|
||||
void update(); // Actualiza la posición del sprite según el recorrido (compatibilidad)
|
||||
void update(float delta_time); // Actualiza la posición del sprite según el recorrido
|
||||
void update(float delta_time); // Actualiza la posición del sprite según el recorrido (delta_time en segundos)
|
||||
void render() override; // Muestra el sprite por pantalla
|
||||
|
||||
// --- Gestión de recorridos ---
|
||||
void addPath(Path path, bool centered = false); // Añade un recorrido (Path)
|
||||
void addPath(const std::vector<SDL_FPoint> &spots, int waiting_counter = 0); // Añade un recorrido a partir de puntos
|
||||
void addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easing_function, int waiting_counter = 0); // Añade un recorrido generado
|
||||
void addPath(const std::vector<SDL_FPoint> &spots, float waiting_time_s = 0.0f); // Añade un recorrido a partir de puntos
|
||||
void addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)> &easing_function, float waiting_time_s = 0.0f); // Añade un recorrido generado
|
||||
|
||||
// --- Estado y control ---
|
||||
void enable(); // Habilita el objeto
|
||||
|
||||
@@ -159,16 +159,18 @@ void Player::move(float deltaTime) {
|
||||
handleRollingMovement();
|
||||
break;
|
||||
case State::TITLE_ANIMATION:
|
||||
handleTitleAnimation();
|
||||
handleTitleAnimation(deltaTime);
|
||||
break;
|
||||
case State::CONTINUE_TIME_OUT:
|
||||
handleContinueTimeOut();
|
||||
break;
|
||||
case State::LEAVING_SCREEN:
|
||||
handleLeavingScreen();
|
||||
updateStepCounter(deltaTime);
|
||||
handleLeavingScreen(deltaTime);
|
||||
break;
|
||||
case State::ENTERING_SCREEN:
|
||||
handleEnteringScreen();
|
||||
updateStepCounter(deltaTime);
|
||||
handleEnteringScreen(deltaTime);
|
||||
break;
|
||||
case State::CREDITS:
|
||||
handleCreditsMovement(deltaTime);
|
||||
@@ -184,22 +186,10 @@ void Player::move(float deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handlePlayingMovement() {
|
||||
// Mueve el jugador a derecha o izquierda
|
||||
pos_x_ += vel_x_;
|
||||
|
||||
// Si el jugador abandona el area de juego por los laterales, restaura su posición
|
||||
const float MIN_X = play_area_.x - 5;
|
||||
const float MAX_X = play_area_.w + 5 - WIDTH;
|
||||
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
|
||||
|
||||
shiftSprite();
|
||||
}
|
||||
|
||||
// Fase 1: Movimiento time-based durante el juego
|
||||
// Movimiento time-based durante el juego
|
||||
void Player::handlePlayingMovement(float deltaTime) {
|
||||
// Mueve el jugador a derecha o izquierda (time-based)
|
||||
pos_x_ += vel_x_ * deltaTime / (1000.0f / 60.0f);
|
||||
// Mueve el jugador a derecha o izquierda (time-based en segundos)
|
||||
pos_x_ += vel_x_ * deltaTime;
|
||||
|
||||
// Si el jugador abandona el area de juego por los laterales, restaura su posición
|
||||
const float MIN_X = play_area_.x - 5;
|
||||
@@ -236,7 +226,7 @@ void Player::handleRollingGroundCollision() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player_sprite_->getVelY() < 2.0F) {
|
||||
if (player_sprite_->getVelY() < 120.0F) { // 2.0F * 60fps = 120.0F pixels/segundo
|
||||
handleRollingStop();
|
||||
} else {
|
||||
handleRollingBounce();
|
||||
@@ -263,10 +253,10 @@ void Player::handleRollingBounce() {
|
||||
playSound("jump.wav");
|
||||
}
|
||||
|
||||
void Player::handleTitleAnimation() {
|
||||
void Player::handleTitleAnimation(float deltaTime) {
|
||||
setInputBasedOnPlayerId();
|
||||
|
||||
pos_x_ += vel_x_ * 2.0F;
|
||||
pos_x_ += (vel_x_ * 2.0F) * deltaTime;
|
||||
const float MIN_X = -WIDTH;
|
||||
const float MAX_X = play_area_.w;
|
||||
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
|
||||
@@ -285,11 +275,11 @@ void Player::handleContinueTimeOut() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleLeavingScreen() {
|
||||
updateStepCounter();
|
||||
void Player::handleLeavingScreen(float deltaTime) {
|
||||
// updateStepCounter se llama desde move() con deltaTime
|
||||
setInputBasedOnPlayerId();
|
||||
|
||||
pos_x_ += vel_x_;
|
||||
pos_x_ += vel_x_ * deltaTime;
|
||||
const float MIN_X = -WIDTH;
|
||||
const float MAX_X = play_area_.w;
|
||||
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
|
||||
@@ -300,15 +290,15 @@ void Player::handleLeavingScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleEnteringScreen() {
|
||||
updateStepCounter();
|
||||
void Player::handleEnteringScreen(float deltaTime) {
|
||||
// updateStepCounter se llama desde move() con deltaTime
|
||||
|
||||
switch (id_) {
|
||||
case Id::PLAYER1:
|
||||
handlePlayer1Entering();
|
||||
handlePlayer1Entering(deltaTime);
|
||||
break;
|
||||
case Id::PLAYER2:
|
||||
handlePlayer2Entering();
|
||||
handlePlayer2Entering(deltaTime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -317,40 +307,27 @@ void Player::handleEnteringScreen() {
|
||||
shiftSprite();
|
||||
}
|
||||
|
||||
void Player::handlePlayer1Entering() {
|
||||
void Player::handlePlayer1Entering(float deltaTime) {
|
||||
setInputPlaying(Input::Action::RIGHT);
|
||||
pos_x_ += vel_x_;
|
||||
pos_x_ += vel_x_ * deltaTime;
|
||||
if (pos_x_ > default_pos_x_) {
|
||||
pos_x_ = default_pos_x_;
|
||||
setPlayingState(State::PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handlePlayer2Entering() {
|
||||
void Player::handlePlayer2Entering(float deltaTime) {
|
||||
setInputPlaying(Input::Action::LEFT);
|
||||
pos_x_ += vel_x_;
|
||||
pos_x_ += vel_x_ * deltaTime;
|
||||
if (pos_x_ < default_pos_x_) {
|
||||
pos_x_ = default_pos_x_;
|
||||
setPlayingState(State::PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleCreditsMovement() {
|
||||
pos_x_ += vel_x_ / 2.0F;
|
||||
|
||||
if (vel_x_ > 0) {
|
||||
handleCreditsRightMovement();
|
||||
} else {
|
||||
handleCreditsLeftMovement();
|
||||
}
|
||||
|
||||
updateWalkingStateForCredits();
|
||||
shiftSprite();
|
||||
}
|
||||
|
||||
// Fase 4: Movimiento general en la pantalla de créditos (time-based)
|
||||
// Movimiento general en la pantalla de créditos (time-based)
|
||||
void Player::handleCreditsMovement(float deltaTime) {
|
||||
pos_x_ += (vel_x_ / 2.0F) * deltaTime / (1000.0f / 60.0f); // Convert frame-based movement to time-based
|
||||
pos_x_ += (vel_x_ / 2.0F) * deltaTime;
|
||||
|
||||
if (vel_x_ > 0) {
|
||||
handleCreditsRightMovement();
|
||||
@@ -376,19 +353,11 @@ void Player::handleCreditsLeftMovement() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::handleWaitingMovement() {
|
||||
++waiting_counter_;
|
||||
if (waiting_counter_ == WAITING_COUNTER) {
|
||||
waiting_counter_ = 0;
|
||||
player_sprite_->resetAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
// Fase 4: Controla la animación del jugador saludando (time-based)
|
||||
// Controla la animación del jugador saludando (time-based)
|
||||
void Player::handleWaitingMovement(float deltaTime) {
|
||||
waiting_time_accumulator_ += deltaTime;
|
||||
float waiting_duration = static_cast<float>(WAITING_COUNTER) * (1000.0f / 60.0f); // Convert frames to milliseconds
|
||||
if (waiting_time_accumulator_ >= waiting_duration) {
|
||||
const float WAITING_DURATION_S = static_cast<float>(WAITING_COUNTER) / 60.0f; // Convert frames to seconds
|
||||
if (waiting_time_accumulator_ >= WAITING_DURATION_S) {
|
||||
waiting_time_accumulator_ = 0.0f;
|
||||
player_sprite_->resetAnimation();
|
||||
}
|
||||
@@ -415,18 +384,11 @@ void Player::setInputBasedOnPlayerId() {
|
||||
}
|
||||
}
|
||||
|
||||
void Player::updateStepCounter() {
|
||||
++step_counter_;
|
||||
if (step_counter_ % 10 == 0) {
|
||||
playSound("walk.wav");
|
||||
}
|
||||
}
|
||||
|
||||
// Fase 4: Incrementa o ajusta el contador de pasos (time-based)
|
||||
// Incrementa o ajusta el contador de pasos (time-based)
|
||||
void Player::updateStepCounter(float deltaTime) {
|
||||
step_time_accumulator_ += deltaTime;
|
||||
float step_interval = 10.0f / 60.0f; // 10 frames converted to seconds
|
||||
if (step_time_accumulator_ >= step_interval) {
|
||||
const float STEP_INTERVAL_S = 10.0f / 60.0f; // 10 frames converted to seconds
|
||||
if (step_time_accumulator_ >= STEP_INTERVAL_S) {
|
||||
step_time_accumulator_ = 0.0f;
|
||||
playSound("walk.wav");
|
||||
}
|
||||
@@ -435,20 +397,20 @@ void Player::updateStepCounter(float deltaTime) {
|
||||
// Pinta el jugador en pantalla
|
||||
void Player::render() {
|
||||
if (power_up_ && isPlaying()) {
|
||||
// Convertir lógica de parpadeo a deltaTime
|
||||
float total_powerup_time_ms = static_cast<float>(POWERUP_COUNTER) / 60.0f * 1000.0f; // Total time in ms
|
||||
float quarter_time_ms = total_powerup_time_ms / 4.0f; // 25% del tiempo total
|
||||
// Convertir lógica de parpadeo a deltaTime en segundos
|
||||
const float TOTAL_POWERUP_TIME_S = static_cast<float>(POWERUP_COUNTER) / 60.0f; // Total time in seconds
|
||||
const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0f; // 25% del tiempo total
|
||||
|
||||
if (power_up_time_accumulator_ > quarter_time_ms) {
|
||||
if (power_up_time_accumulator_ > QUARTER_TIME_S) {
|
||||
// En los primeros 75% del tiempo, siempre visible
|
||||
power_sprite_->render();
|
||||
} else {
|
||||
// En el último 25%, parpadea cada 20 frames (333ms aprox)
|
||||
constexpr float blink_period_ms = 20.0f / 60.0f * 1000.0f; // 20 frames in ms
|
||||
constexpr float visible_proportion = 4.0f / 20.0f; // 4 frames visible de 20 total
|
||||
// En el último 25%, parpadea cada 20 frames (≈0.333s)
|
||||
constexpr float BLINK_PERIOD_S = 20.0f / 60.0f; // 20 frames in seconds
|
||||
constexpr float VISIBLE_PROPORTION = 4.0f / 20.0f; // 4 frames visible de 20 total
|
||||
|
||||
float cycle_position = fmod(power_up_time_accumulator_, blink_period_ms) / blink_period_ms;
|
||||
if (cycle_position >= visible_proportion) {
|
||||
float cycle_position = fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
|
||||
if (cycle_position >= VISIBLE_PROPORTION) {
|
||||
power_sprite_->render();
|
||||
}
|
||||
}
|
||||
@@ -677,15 +639,15 @@ void Player::setPlayingState(State state) {
|
||||
case State::ROLLING: {
|
||||
// Activa la animación de rodar dando botes
|
||||
player_sprite_->setCurrentAnimation("rolling");
|
||||
player_sprite_->setAnimationSpeed(4);
|
||||
player_sprite_->setVelY(-6.6F); // Velocidad inicial
|
||||
player_sprite_->setAccelY(0.2F); // Gravedad
|
||||
player_sprite_->setAnimationSpeed(4.0f / 60.0f); // 4 frames convertido a segundos
|
||||
player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s)
|
||||
player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²)
|
||||
player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies
|
||||
(rand() % 2 == 0) ? player_sprite_->setVelX(3.3F) : player_sprite_->setVelX(-3.3F);
|
||||
(rand() % 2 == 0) ? player_sprite_->setVelX(198.0F) : player_sprite_->setVelX(-198.0F); // 3.3 * 60 = 198 pixels/s
|
||||
break;
|
||||
}
|
||||
case State::TITLE_ANIMATION: {
|
||||
// Activa la animación de rodar
|
||||
// Activa la animación de caminar
|
||||
player_sprite_->setCurrentAnimation("walk");
|
||||
playSound("voice_credit_thankyou.wav");
|
||||
break;
|
||||
@@ -697,11 +659,11 @@ void Player::setPlayingState(State state) {
|
||||
}
|
||||
case State::CONTINUE_TIME_OUT: {
|
||||
// Activa la animación de sacar al jugador de la zona de juego
|
||||
player_sprite_->setAccelY(0.2F);
|
||||
player_sprite_->setVelY(-4.0F);
|
||||
player_sprite_->setAccelY(720.0F); // 0.2 * 60² = 720 pixels/s²
|
||||
player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s
|
||||
player_sprite_->setVelX(0.0F);
|
||||
player_sprite_->setCurrentAnimation("rolling");
|
||||
player_sprite_->setAnimationSpeed(5);
|
||||
player_sprite_->setAnimationSpeed(5.0f / 60.0f); // 5 frames convertido a segundos
|
||||
setScoreboardMode(Scoreboard::Mode::GAME_OVER);
|
||||
playSound("voice_aw_aw_aw.wav");
|
||||
playSound("jump.wav");
|
||||
@@ -772,7 +734,7 @@ void Player::decScoreMultiplier() {
|
||||
void Player::setInvulnerable(bool value) {
|
||||
invulnerable_ = value;
|
||||
invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0;
|
||||
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f * 1000.0f : 0.0f; // Convert frames to milliseconds
|
||||
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Convert frames to seconds
|
||||
}
|
||||
|
||||
// Monitoriza el estado (time-based)
|
||||
@@ -781,16 +743,16 @@ void Player::updateInvulnerable(float deltaTime) {
|
||||
if (invulnerable_time_accumulator_ > 0) {
|
||||
invulnerable_time_accumulator_ -= deltaTime;
|
||||
|
||||
// Frecuencia fija de parpadeo adaptada a deltaTime (en milisegundos)
|
||||
constexpr float blink_period_ms = 8.0f / 60.0f * 1000.0f; // 8 frames convertidos a ms
|
||||
// Frecuencia fija de parpadeo adaptada a deltaTime (en segundos)
|
||||
constexpr float BLINK_PERIOD_S = 8.0f / 60.0f; // 8 frames convertidos a segundos
|
||||
|
||||
// Calcula proporción decreciente basada en tiempo restante
|
||||
float total_invulnerable_time_ms = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f * 1000.0f;
|
||||
float progress = 1.0f - (invulnerable_time_accumulator_ / total_invulnerable_time_ms);
|
||||
const float TOTAL_INVULNERABLE_TIME_S = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f;
|
||||
float progress = 1.0f - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S);
|
||||
float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final
|
||||
|
||||
// Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal
|
||||
float cycle_position = fmod(invulnerable_time_accumulator_, blink_period_ms) / blink_period_ms;
|
||||
float cycle_position = fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
|
||||
bool should_show_invulnerable = cycle_position < white_proportion;
|
||||
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
|
||||
|
||||
@@ -811,7 +773,7 @@ void Player::updateInvulnerable(float deltaTime) {
|
||||
void Player::setPowerUp() {
|
||||
power_up_ = true;
|
||||
power_up_counter_ = POWERUP_COUNTER;
|
||||
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f * 1000.0f; // Convert frames to milliseconds
|
||||
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f; // Convert frames to seconds
|
||||
}
|
||||
|
||||
// Actualiza el valor de la variable (time-based)
|
||||
@@ -863,9 +825,9 @@ void Player::setPlayerTextures(const std::vector<std::shared_ptr<Texture>> &text
|
||||
void Player::updateContinueCounter(float deltaTime) {
|
||||
if (playing_state_ == State::CONTINUE) {
|
||||
continue_time_accumulator_ += deltaTime;
|
||||
constexpr float CONTINUE_INTERVAL = 1000.0f; // 1 segundo en milisegundos
|
||||
if (continue_time_accumulator_ >= CONTINUE_INTERVAL) {
|
||||
continue_time_accumulator_ -= CONTINUE_INTERVAL;
|
||||
constexpr float CONTINUE_INTERVAL_S = 1.0f; // 1 segundo
|
||||
if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) {
|
||||
continue_time_accumulator_ -= CONTINUE_INTERVAL_S;
|
||||
decContinueCounter();
|
||||
}
|
||||
}
|
||||
@@ -875,9 +837,9 @@ void Player::updateContinueCounter(float deltaTime) {
|
||||
void Player::updateEnterNameCounter(float deltaTime) {
|
||||
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
|
||||
name_entry_time_accumulator_ += deltaTime;
|
||||
constexpr float NAME_ENTRY_INTERVAL = 1000.0f; // 1 segundo en milisegundos
|
||||
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL) {
|
||||
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL;
|
||||
constexpr float NAME_ENTRY_INTERVAL_S = 1.0f; // 1 segundo
|
||||
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL_S) {
|
||||
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL_S;
|
||||
decNameEntryCounter();
|
||||
}
|
||||
}
|
||||
@@ -887,8 +849,8 @@ void Player::updateEnterNameCounter(float deltaTime) {
|
||||
void Player::updateShowingName(float deltaTime) {
|
||||
if (playing_state_ == State::SHOWING_NAME) {
|
||||
showing_name_time_accumulator_ += deltaTime;
|
||||
constexpr float SHOWING_NAME_DURATION = 5000.0f; // 5 segundos en milisegundos
|
||||
if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION) {
|
||||
constexpr float SHOWING_NAME_DURATION_S = 5.0f; // 5 segundos
|
||||
if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION_S) {
|
||||
game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE);
|
||||
}
|
||||
}
|
||||
@@ -909,13 +871,16 @@ void Player::decContinueCounter() {
|
||||
void Player::decNameEntryCounter() {
|
||||
name_entry_time_accumulator_ = 0.0f; // Reset time accumulator
|
||||
|
||||
// Incrementa acumuladores de tiempo (1 segundo = 1000ms)
|
||||
name_entry_idle_time_accumulator_ += 1000.0f;
|
||||
name_entry_total_time_accumulator_ += 1000.0f;
|
||||
// Incrementa acumuladores de tiempo (1 segundo)
|
||||
name_entry_idle_time_accumulator_ += 1.0f;
|
||||
name_entry_total_time_accumulator_ += 1.0f;
|
||||
|
||||
// Comprueba los acumuladores directamente contra los límites en milisegundos
|
||||
if ((name_entry_total_time_accumulator_ >= param.game.name_entry_total_time) ||
|
||||
(name_entry_idle_time_accumulator_ >= param.game.name_entry_idle_time)) {
|
||||
// Convierte límites de param (milisegundos) a segundos para comparación
|
||||
const float NAME_ENTRY_TOTAL_TIME_S = param.game.name_entry_total_time / 1000.0f;
|
||||
const float NAME_ENTRY_IDLE_TIME_S = param.game.name_entry_idle_time / 1000.0f;
|
||||
|
||||
if ((name_entry_total_time_accumulator_ >= NAME_ENTRY_TOTAL_TIME_S) ||
|
||||
(name_entry_idle_time_accumulator_ >= NAME_ENTRY_IDLE_TIME_S)) {
|
||||
name_entry_total_time_accumulator_ = 0.0f;
|
||||
name_entry_idle_time_accumulator_ = 0.0f;
|
||||
if (playing_state_ == State::ENTERING_NAME) {
|
||||
@@ -1036,7 +1001,7 @@ void Player::updateVisualLine(float deltaTime) {
|
||||
// Inicia un disparo en ambas líneas
|
||||
void Player::startFiringSystem(int cooldown_frames) {
|
||||
// LÍNEA 1: Inicia cooldown funcional
|
||||
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0f * 1000.0f; // Convertir frames a ms
|
||||
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0f; // Convertir frames a segundos
|
||||
can_fire_new_system_ = false;
|
||||
|
||||
// LÍNEA 2: Resetea completamente el estado visual
|
||||
|
||||
@@ -207,7 +207,7 @@ class Player {
|
||||
|
||||
private:
|
||||
// --- Constantes de física y movimiento ---
|
||||
static constexpr float BASE_SPEED = 1.5F; // Velocidad base del jugador
|
||||
static constexpr float BASE_SPEED = 90.0f; // Velocidad base del jugador (pixels/segundo)
|
||||
|
||||
// --- Constantes de power-ups y estados especiales ---
|
||||
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp (frames)
|
||||
@@ -224,8 +224,8 @@ class Player {
|
||||
// --- Constantes del nuevo sistema de disparo de dos líneas ---
|
||||
static constexpr float AIMING_DURATION_FACTOR = 0.5f; // 50% del cooldown funcional
|
||||
static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0f; // 4 veces la duración de aiming
|
||||
static constexpr float THREAT_POSE_DURATION = 833.33f; // 50 frames = ~833ms (duración base)
|
||||
static constexpr float MIN_THREAT_POSE_DURATION = 100.0f; // Duración mínima para threat pose
|
||||
static constexpr float THREAT_POSE_DURATION = 50.0f / 60.0f; // 50 frames = ~0.833s (duración base)
|
||||
static constexpr float MIN_THREAT_POSE_DURATION = 6.0f / 60.0f; // 6 frames = ~0.1s (duración mínima)
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
|
||||
@@ -346,12 +346,12 @@ class Player {
|
||||
void handleRollingGroundCollision(); // Gestiona la interacción del objeto rodante con el suelo (rebotes, frenado, etc.)
|
||||
void handleRollingStop(); // Detiene el movimiento del objeto rodante cuando se cumplen las condiciones necesarias
|
||||
void handleRollingBounce(); // Aplica una lógica de rebote al colisionar con superficies durante el rodamiento
|
||||
void handleTitleAnimation(); // Ejecuta la animación del título en pantalla (ej. entrada, parpadeo o desplazamiento)
|
||||
void handleTitleAnimation(float deltaTime); // Ejecuta la animación del título en pantalla (ej. entrada, parpadeo o desplazamiento)
|
||||
void handleContinueTimeOut(); // Gestiona el tiempo de espera en la pantalla de "Continuar" y decide si pasar a otro estado
|
||||
void handleLeavingScreen(); // Lógica para salir de la pantalla actual (transición visual o cambio de escena)
|
||||
void handleEnteringScreen(); // Lógica para entrar en una nueva pantalla, posiblemente con animación o retraso
|
||||
void handlePlayer1Entering(); // Controla la animación o posición de entrada del Jugador 1 en pantalla
|
||||
void handlePlayer2Entering(); // Controla la animación o posición de entrada del Jugador 2 en pantalla
|
||||
void handleLeavingScreen(float deltaTime); // Lógica para salir de la pantalla actual (transición visual o cambio de escena)
|
||||
void handleEnteringScreen(float deltaTime); // Lógica para entrar en una nueva pantalla, posiblemente con animación o retraso
|
||||
void handlePlayer1Entering(float deltaTime); // Controla la animación o posición de entrada del Jugador 1 en pantalla
|
||||
void handlePlayer2Entering(float deltaTime); // Controla la animación o posición de entrada del Jugador 2 en pantalla
|
||||
void handleCreditsMovement(); // Movimiento general en la pantalla de créditos (frame-based)
|
||||
void handleCreditsMovement(float deltaTime); // Movimiento general en la pantalla de créditos (time-based)
|
||||
void handleCreditsRightMovement(); // Lógica específica para mover los créditos hacia la derecha
|
||||
|
||||
@@ -49,16 +49,17 @@ Credits::Credits()
|
||||
|
||||
fade_in_->setColor(param.fade.color);
|
||||
fade_in_->setType(Fade::Type::FULLSCREEN);
|
||||
fade_in_->setPostDuration(50);
|
||||
fade_in_->setPostDuration(static_cast<int>(50 * (1000.0f / 60.0f))); // 50 frames = ~833ms
|
||||
fade_in_->setMode(Fade::Mode::IN);
|
||||
fade_in_->activate();
|
||||
|
||||
fade_out_->setColor(0, 0, 0);
|
||||
fade_out_->setType(Fade::Type::FULLSCREEN);
|
||||
fade_out_->setPostDuration(400);
|
||||
fade_out_->setPostDuration(static_cast<int>(400 * (1000.0f / 60.0f))); // 400 frames = ~6667ms
|
||||
|
||||
updateRedRect();
|
||||
tiled_bg_->setColor(Color(255, 96, 96));
|
||||
tiled_bg_->setSpeed(60.0F);
|
||||
|
||||
initPlayers();
|
||||
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
|
||||
@@ -81,7 +82,7 @@ Credits::~Credits() {
|
||||
// Calcula el deltatime
|
||||
auto Credits::calculateDeltaTime() -> float {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -112,8 +113,8 @@ void Credits::update(float deltaTime) {
|
||||
updatePlayers(adjusted_delta_time);
|
||||
updateAllFades(adjusted_delta_time);
|
||||
|
||||
// Convertir deltaTime a factor de frame (asumiendo 60fps)
|
||||
const float frameFactor = adjusted_delta_time / (1000.0f / 60.0f);
|
||||
// Convertir deltaTime a equivalente de frames (60fps)
|
||||
const float frameFactor = adjusted_delta_time * 60.0f;
|
||||
counter_ += frameFactor;
|
||||
|
||||
Screen::get()->update();
|
||||
@@ -287,43 +288,14 @@ void Credits::fillCanvas() {
|
||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
||||
}
|
||||
|
||||
// Actualiza el destino de los rectangulos de las texturas (frame-based)
|
||||
void Credits::updateTextureDstRects() {
|
||||
if (static_cast<int>(counter_) % 10 == 0) {
|
||||
// Comprueba la posición de la textura con los titulos de credito
|
||||
if (credits_rect_dst_.y + credits_rect_dst_.h > play_area_.y) {
|
||||
--credits_rect_dst_.y;
|
||||
}
|
||||
|
||||
// Comprueba la posición de la textura con el mini_logo
|
||||
if (mini_logo_rect_dst_.y == mini_logo_final_pos_) {
|
||||
mini_logo_on_position_ = true;
|
||||
|
||||
// Si el jugador quiere pasar los titulos de credito, el fade se inicia solo
|
||||
if (want_to_pass_) {
|
||||
fading_ = true;
|
||||
}
|
||||
|
||||
// Se activa el contador para evitar que la sección sea infinita
|
||||
if (counter_prevent_endless_ == 1000) {
|
||||
fading_ = true;
|
||||
} else {
|
||||
++counter_prevent_endless_;
|
||||
}
|
||||
} else {
|
||||
--mini_logo_rect_dst_.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el destino de los rectangulos de las texturas (time-based)
|
||||
void Credits::updateTextureDstRects(float deltaTime) {
|
||||
constexpr float TEXTURE_UPDATE_INTERVAL = 10 * (1000.0f / 60.0f); // 166.67ms (cada 10 frames)
|
||||
constexpr float TEXTURE_UPDATE_INTERVAL_S = 10.0f / 60.0f; // ~0.167s (cada 10 frames)
|
||||
static float texture_accumulator = 0.0f;
|
||||
texture_accumulator += deltaTime;
|
||||
|
||||
if (texture_accumulator >= TEXTURE_UPDATE_INTERVAL) {
|
||||
texture_accumulator -= TEXTURE_UPDATE_INTERVAL;
|
||||
if (texture_accumulator >= TEXTURE_UPDATE_INTERVAL_S) {
|
||||
texture_accumulator -= TEXTURE_UPDATE_INTERVAL_S;
|
||||
|
||||
// Comprueba la posición de la textura con los titulos de credito
|
||||
if (credits_rect_dst_.y + credits_rect_dst_.h > play_area_.y) {
|
||||
@@ -351,31 +323,12 @@ void Credits::updateTextureDstRects(float deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tira globos al escenario (frame-based)
|
||||
void Credits::throwBalloons() {
|
||||
constexpr int SPEED = 200;
|
||||
const std::vector<int> SETS = {0, 63, 25, 67, 17, 75, 13, 50};
|
||||
|
||||
if (counter_ > ((SETS.size() - 1) * SPEED) * 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<int>(counter_) % SPEED == 0) {
|
||||
const int INDEX = (static_cast<int>(counter_) / SPEED) % SETS.size();
|
||||
balloon_manager_->deployFormation(SETS.at(INDEX), -60);
|
||||
}
|
||||
|
||||
if (static_cast<int>(counter_) % (SPEED * 4) == 0 && counter_ > 0) {
|
||||
balloon_manager_->createPowerBall();
|
||||
}
|
||||
}
|
||||
|
||||
// Tira globos al escenario (time-based)
|
||||
void Credits::throwBalloons(float deltaTime) {
|
||||
constexpr int SPEED = 200;
|
||||
const std::vector<int> SETS = {0, 63, 25, 67, 17, 75, 13, 50};
|
||||
constexpr float BALLOON_INTERVAL = SPEED * (1000.0f / 60.0f); // 3333.33ms (cada 200 frames)
|
||||
constexpr float POWERBALL_INTERVAL = (SPEED * 4) * (1000.0f / 60.0f); // 13333.33ms (cada 800 frames)
|
||||
constexpr float BALLOON_INTERVAL_S = SPEED / 60.0f; // ~3.33s (cada 200 frames)
|
||||
constexpr float POWERBALL_INTERVAL_S = (SPEED * 4) / 60.0f; // ~13.33s (cada 800 frames)
|
||||
|
||||
if (counter_ > ((SETS.size() - 1) * SPEED) * 3) {
|
||||
return;
|
||||
@@ -387,14 +340,14 @@ void Credits::throwBalloons(float deltaTime) {
|
||||
balloon_accumulator += deltaTime;
|
||||
powerball_accumulator += deltaTime;
|
||||
|
||||
if (balloon_accumulator >= BALLOON_INTERVAL) {
|
||||
balloon_accumulator -= BALLOON_INTERVAL;
|
||||
if (balloon_accumulator >= BALLOON_INTERVAL_S) {
|
||||
balloon_accumulator -= BALLOON_INTERVAL_S;
|
||||
const int INDEX = (static_cast<int>(counter_ / SPEED)) % SETS.size();
|
||||
balloon_manager_->deployFormation(SETS.at(INDEX), -60);
|
||||
}
|
||||
|
||||
if (powerball_accumulator >= POWERBALL_INTERVAL && counter_ > 0) {
|
||||
powerball_accumulator -= POWERBALL_INTERVAL;
|
||||
if (powerball_accumulator >= POWERBALL_INTERVAL_S && counter_ > 0) {
|
||||
powerball_accumulator -= POWERBALL_INTERVAL_S;
|
||||
balloon_manager_->createPowerBall();
|
||||
}
|
||||
}
|
||||
@@ -466,60 +419,17 @@ void Credits::initPlayers() {
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los rectangulos negros (frame-based)
|
||||
void Credits::updateBlackRects() {
|
||||
static int current_step_ = steps_;
|
||||
if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) {
|
||||
// Si los rectangulos superior e inferior no han llegado al centro
|
||||
if (static_cast<int>(counter_) % 4 == 0) {
|
||||
// Incrementa la altura del rectangulo superior
|
||||
top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1);
|
||||
|
||||
// Incrementa la altura y modifica la posición del rectangulo inferior
|
||||
++bottom_black_rect_.h;
|
||||
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1);
|
||||
|
||||
--current_step_;
|
||||
setVolume((initial_volume_ * current_step_ / steps_));
|
||||
}
|
||||
} else {
|
||||
// Si los rectangulos superior e inferior han llegado al centro
|
||||
if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x) {
|
||||
constexpr int SPEED = 2;
|
||||
// Si los rectangulos izquierdo y derecho no han llegado al centro
|
||||
// Incrementa la anchura del rectangulo situado a la izquierda
|
||||
left_black_rect_.w = std::min(left_black_rect_.w + SPEED, param.game.game_area.center_x);
|
||||
|
||||
// Incrementa la anchura y modifica la posición del rectangulo situado a la derecha
|
||||
right_black_rect_.w += SPEED;
|
||||
right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x);
|
||||
|
||||
--current_step_;
|
||||
setVolume((initial_volume_ * current_step_ / steps_));
|
||||
} else {
|
||||
// Si los rectangulos izquierdo y derecho han llegado al centro
|
||||
setVolume(0);
|
||||
Audio::get()->stopMusic();
|
||||
if (counter_pre_fade_ == 400) {
|
||||
fade_out_->activate();
|
||||
} else {
|
||||
++counter_pre_fade_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los rectangulos negros (time-based)
|
||||
void Credits::updateBlackRects(float deltaTime) {
|
||||
static float current_step_ = static_cast<float>(steps_);
|
||||
constexpr float BLACK_RECT_INTERVAL = 4 * (1000.0f / 60.0f); // 66.67ms (cada 4 frames)
|
||||
constexpr float BLACK_RECT_INTERVAL_S = 4.0f / 60.0f; // ~0.067s (cada 4 frames)
|
||||
static float black_rect_accumulator = 0.0f;
|
||||
|
||||
if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) {
|
||||
// Si los rectangulos superior e inferior no han llegado al centro
|
||||
black_rect_accumulator += deltaTime;
|
||||
if (black_rect_accumulator >= BLACK_RECT_INTERVAL) {
|
||||
black_rect_accumulator -= BLACK_RECT_INTERVAL;
|
||||
if (black_rect_accumulator >= BLACK_RECT_INTERVAL_S) {
|
||||
black_rect_accumulator -= BLACK_RECT_INTERVAL_S;
|
||||
|
||||
// Incrementa la altura del rectangulo superior
|
||||
top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1);
|
||||
@@ -552,8 +462,8 @@ void Credits::updateBlackRects(float deltaTime) {
|
||||
if (counter_pre_fade_ == 400) {
|
||||
fade_out_->activate();
|
||||
} else {
|
||||
// Convertir deltaTime a factor de frame
|
||||
const float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
// Convertir deltaTime a equivalente de frames
|
||||
const float frameFactor = deltaTime * 60.0f;
|
||||
counter_pre_fade_ += frameFactor;
|
||||
}
|
||||
}
|
||||
@@ -568,24 +478,6 @@ void Credits::updateRedRect() {
|
||||
border_rect_.h = bottom_black_rect_.y - border_rect_.y + 1;
|
||||
}
|
||||
|
||||
// Actualiza el estado de fade (frame-based)
|
||||
void Credits::updateAllFades() {
|
||||
if (fading_) {
|
||||
updateBlackRects();
|
||||
updateRedRect();
|
||||
}
|
||||
|
||||
fade_in_->update();
|
||||
if (fade_in_->hasEnded()) {
|
||||
Audio::get()->playMusic("credits.ogg");
|
||||
}
|
||||
|
||||
fade_out_->update();
|
||||
if (fade_out_->hasEnded()) {
|
||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el estado de fade (time-based)
|
||||
void Credits::updateAllFades(float deltaTime) {
|
||||
if (fading_) {
|
||||
|
||||
@@ -79,7 +79,7 @@ Game::Game(Player::Id player_id, int current_stage, bool demo)
|
||||
scoreboard_ = Scoreboard::get();
|
||||
|
||||
fade_in_->setColor(param.fade.color);
|
||||
fade_in_->setPreDuration(demo_.enabled ? DEMO_FADE_PRE_DURATION_MS : 0);
|
||||
fade_in_->setPreDuration(demo_.enabled ? static_cast<int>(DEMO_FADE_PRE_DURATION_S * 1000) : 0);
|
||||
fade_in_->setPostDuration(0);
|
||||
fade_in_->setType(Fade::Type::RANDOM_SQUARE2);
|
||||
fade_in_->setMode(Fade::Mode::IN);
|
||||
@@ -322,18 +322,18 @@ void Game::updateGameStateGameOver(float deltaTime) {
|
||||
updateBullets(deltaTime);
|
||||
updateItems(deltaTime);
|
||||
updateSmartSprites(deltaTime);
|
||||
updatePathSprites();
|
||||
updatePathSprites(deltaTime);
|
||||
updateTimeStopped(deltaTime);
|
||||
checkBulletCollision();
|
||||
cleanVectors();
|
||||
|
||||
if (game_over_timer_ < GAME_OVER_DURATION_MS) {
|
||||
if (game_over_timer_ < GAME_OVER_DURATION_S) {
|
||||
handleGameOverEvents(); // Maneja eventos al inicio
|
||||
|
||||
game_over_timer_ += deltaTime; // Incremento time-based
|
||||
|
||||
constexpr float FADE_TRIGGER_MS = GAME_OVER_DURATION_MS - (150.0f * (1000.0f / 60.0f)); // 2500ms antes del final
|
||||
if (game_over_timer_ >= FADE_TRIGGER_MS && !fade_out_->isEnabled()) {
|
||||
constexpr float FADE_TRIGGER_S = GAME_OVER_DURATION_S - 2.5f; // 2.5 segundos antes del final
|
||||
if (game_over_timer_ >= FADE_TRIGGER_S && !fade_out_->isEnabled()) {
|
||||
fade_out_->activate();
|
||||
}
|
||||
}
|
||||
@@ -369,7 +369,7 @@ void Game::updateGameStateCompleted(float deltaTime) {
|
||||
updateBullets(deltaTime);
|
||||
updateItems(deltaTime);
|
||||
updateSmartSprites(deltaTime);
|
||||
updatePathSprites();
|
||||
updatePathSprites(deltaTime);
|
||||
cleanVectors();
|
||||
|
||||
// Maneja eventos del juego completado
|
||||
@@ -737,8 +737,8 @@ void Game::createItemText(int x, const std::shared_ptr<Texture> &texture) {
|
||||
path_sprites_.back()->setWidth(W);
|
||||
path_sprites_.back()->setHeight(H);
|
||||
path_sprites_.back()->setSpriteClip({0, 0, static_cast<float>(W), static_cast<float>(H)});
|
||||
path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 100, easeOutQuint, 0);
|
||||
path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 80, easeInQuint, 0);
|
||||
path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 1.667f, easeOutQuint, 0); // 100 frames → 1.667s
|
||||
path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 1.333f, easeInQuint, 0); // 80 frames → 1.333s
|
||||
path_sprites_.back()->enable();
|
||||
}
|
||||
|
||||
@@ -783,14 +783,14 @@ void Game::throwCoffee(int x, int y) {
|
||||
smart_sprites_.back()->setPosY(y - 8);
|
||||
smart_sprites_.back()->setWidth(param.game.item_size);
|
||||
smart_sprites_.back()->setHeight(param.game.item_size);
|
||||
smart_sprites_.back()->setVelX(-1.0F + ((rand() % 5) * 0.5F));
|
||||
smart_sprites_.back()->setVelY(-4.0F);
|
||||
smart_sprites_.back()->setVelX((-1.0F + ((rand() % 5) * 0.5F)) * 60.0f); // Convertir a pixels/segundo
|
||||
smart_sprites_.back()->setVelY(-4.0F * 60.0f); // Convertir a pixels/segundo
|
||||
smart_sprites_.back()->setAccelX(0.0F);
|
||||
smart_sprites_.back()->setAccelY(0.2F);
|
||||
smart_sprites_.back()->setAccelY(0.2F * 60.0f * 60.0f); // Convertir a pixels/segundo² (0.2 × 60²)
|
||||
smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50));
|
||||
smart_sprites_.back()->setDestY(param.game.height + 1);
|
||||
smart_sprites_.back()->setEnabled(true);
|
||||
smart_sprites_.back()->setFinishedCounter(1);
|
||||
smart_sprites_.back()->setFinishedDelay(0.0F);
|
||||
smart_sprites_.back()->setSpriteClip(0, param.game.item_size, param.game.item_size, param.game.item_size);
|
||||
smart_sprites_.back()->setRotatingCenter({param.game.item_size / 2, param.game.item_size / 2});
|
||||
smart_sprites_.back()->setRotate(true);
|
||||
@@ -813,9 +813,9 @@ void Game::renderSmartSprites() {
|
||||
}
|
||||
|
||||
// Actualiza los PathSprites
|
||||
void Game::updatePathSprites() {
|
||||
void Game::updatePathSprites(float deltaTime) {
|
||||
for (auto &sprite : path_sprites_) {
|
||||
sprite->update();
|
||||
sprite->update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,23 +859,23 @@ void Game::handlePlayerCollision(std::shared_ptr<Player> &player, std::shared_pt
|
||||
|
||||
// Actualiza el estado del tiempo detenido
|
||||
void Game::updateTimeStopped(float deltaTime) {
|
||||
static constexpr float WARNING_THRESHOLD_MS = 2000.0f; // 120 frames a 60fps
|
||||
static constexpr float CLOCK_SOUND_INTERVAL_MS = 500.0f; // 30 frames a 60fps
|
||||
static constexpr float COLOR_FLASH_INTERVAL_MS = 250.0f; // 15 frames a 60fps
|
||||
static constexpr float WARNING_THRESHOLD_S = 2.0f; // 120 frames a 60fps → segundos
|
||||
static constexpr float CLOCK_SOUND_INTERVAL_S = 0.5f; // 30 frames a 60fps → segundos
|
||||
static constexpr float COLOR_FLASH_INTERVAL_S = 0.25f; // 15 frames a 60fps → segundos
|
||||
|
||||
if (time_stopped_timer_ > 0) {
|
||||
time_stopped_timer_ -= deltaTime;
|
||||
|
||||
// Fase de advertencia (últimos 2 segundos)
|
||||
if (time_stopped_timer_ <= WARNING_THRESHOLD_MS) {
|
||||
if (time_stopped_timer_ <= WARNING_THRESHOLD_S) {
|
||||
static float last_sound_time = 0.0f;
|
||||
last_sound_time += deltaTime;
|
||||
|
||||
if (last_sound_time >= CLOCK_SOUND_INTERVAL_MS) {
|
||||
if (last_sound_time >= CLOCK_SOUND_INTERVAL_S) {
|
||||
balloon_manager_->normalColorsToAllBalloons();
|
||||
playSound("clock.wav");
|
||||
last_sound_time = 0.0f;
|
||||
} else if (last_sound_time >= COLOR_FLASH_INTERVAL_MS) {
|
||||
} else if (last_sound_time >= COLOR_FLASH_INTERVAL_S) {
|
||||
balloon_manager_->reverseColorsToAllBalloons();
|
||||
playSound("clock.wav");
|
||||
}
|
||||
@@ -883,7 +883,7 @@ void Game::updateTimeStopped(float deltaTime) {
|
||||
// Fase normal - solo sonido ocasional
|
||||
static float sound_timer = 0.0f;
|
||||
sound_timer += deltaTime;
|
||||
if (sound_timer >= CLOCK_SOUND_INTERVAL_MS) {
|
||||
if (sound_timer >= CLOCK_SOUND_INTERVAL_S) {
|
||||
playSound("clock.wav");
|
||||
sound_timer = 0.0f;
|
||||
}
|
||||
@@ -978,7 +978,7 @@ void Game::fillCanvas() {
|
||||
void Game::enableTimeStopItem() {
|
||||
balloon_manager_->stopAllBalloons();
|
||||
balloon_manager_->reverseColorsToAllBalloons();
|
||||
time_stopped_timer_ = TIME_STOPPED_DURATION_MS;
|
||||
time_stopped_timer_ = TIME_STOPPED_DURATION_S;
|
||||
}
|
||||
|
||||
// Deshabilita el efecto del item de detener el tiempo
|
||||
@@ -988,12 +988,12 @@ void Game::disableTimeStopItem() {
|
||||
balloon_manager_->normalColorsToAllBalloons();
|
||||
}
|
||||
|
||||
// Calcula el deltatime
|
||||
// Calcula el deltatime en segundos
|
||||
auto Game::calculateDeltaTime() -> float {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time_ms = static_cast<float>(current_time - last_time_);
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
return delta_time_ms / 1000.0f; // Convertir de milisegundos a segundos
|
||||
}
|
||||
|
||||
// Bucle para el juego
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1546,21 +1546,21 @@ void Game::initDifficultyVars() {
|
||||
// Variables relacionadas con la dificultad
|
||||
switch (difficulty_) {
|
||||
case Difficulty::Code::EASY: {
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::SPEED.at(0));
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::GAME_TEMPO.at(0));
|
||||
difficulty_score_multiplier_ = 0.5F;
|
||||
scoreboard_->setColor(param.scoreboard.easy_color);
|
||||
break;
|
||||
}
|
||||
|
||||
case Difficulty::Code::NORMAL: {
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::SPEED.at(0));
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::GAME_TEMPO.at(0));
|
||||
difficulty_score_multiplier_ = 1.0F;
|
||||
scoreboard_->setColor(param.scoreboard.normal_color);
|
||||
break;
|
||||
}
|
||||
|
||||
case Difficulty::Code::HARD: {
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::SPEED.at(4));
|
||||
balloon_manager_->setDefaultBalloonSpeed(Balloon::GAME_TEMPO.at(4));
|
||||
difficulty_score_multiplier_ = 1.5F;
|
||||
scoreboard_->setColor(param.scoreboard.hard_color);
|
||||
break;
|
||||
@@ -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 {
|
||||
@@ -1731,10 +1738,18 @@ void Game::updateGameStateShowingGetReadyMessage(float deltaTime) {
|
||||
if (path_sprites_.empty()) {
|
||||
setState(State::PLAYING);
|
||||
}
|
||||
if (counter_ == 100) {
|
||||
playMusic();
|
||||
|
||||
// Reproducir música después de ~1.67 segundos (100 frames a 60fps)
|
||||
static bool music_started = false;
|
||||
static float music_timer = 0.0f;
|
||||
if (!music_started) {
|
||||
music_timer += deltaTime;
|
||||
if (music_timer >= 1.67f) {
|
||||
playMusic();
|
||||
music_started = true;
|
||||
setState(State::PLAYING);
|
||||
}
|
||||
}
|
||||
++counter_;
|
||||
}
|
||||
|
||||
// Actualiza las variables durante el transcurso normal del juego
|
||||
@@ -1754,7 +1769,7 @@ void Game::updateGameStatePlaying(float deltaTime) {
|
||||
updateItems(deltaTime);
|
||||
updateStage();
|
||||
updateSmartSprites(deltaTime);
|
||||
updatePathSprites();
|
||||
updatePathSprites(deltaTime);
|
||||
updateTimeStopped(deltaTime);
|
||||
updateHelper();
|
||||
checkBulletCollision();
|
||||
@@ -1813,9 +1828,9 @@ void Game::checkAndUpdateBalloonSpeed() {
|
||||
|
||||
for (size_t i = 0; i < std::size(THRESHOLDS); ++i) {
|
||||
// Si la velocidad actual del globo es la correspondiente al umbral "i" y el porcentaje de progreso ha superado ese umbral
|
||||
if (balloon_manager_->getBalloonSpeed() == Balloon::SPEED.at(i) && PERCENT > THRESHOLDS.at(i)) {
|
||||
if (balloon_manager_->getBalloonSpeed() == Balloon::GAME_TEMPO.at(i) && PERCENT > THRESHOLDS.at(i)) {
|
||||
// Sube la velocidad al siguiente nivel (i + 1)
|
||||
balloon_manager_->setBalloonSpeed(Balloon::SPEED.at(i + 1));
|
||||
balloon_manager_->setBalloonSpeed(Balloon::GAME_TEMPO.at(i + 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1895,12 +1910,12 @@ void Game::onPauseStateChanged(bool is_paused) {
|
||||
|
||||
// Maneja eventos del juego completado usando flags para triggers únicos
|
||||
void Game::handleGameCompletedEvents() {
|
||||
constexpr float START_CELEBRATIONS_MS = 6667.0f; // 400 frames a 60fps
|
||||
constexpr float END_CELEBRATIONS_MS = 11667.0f; // 700 frames a 60fps
|
||||
constexpr float START_CELEBRATIONS_S = 6.667f; // 400 frames a 60fps → segundos
|
||||
constexpr float END_CELEBRATIONS_S = 11.667f; // 700 frames a 60fps → segundos
|
||||
|
||||
// Inicio de celebraciones
|
||||
static bool start_celebrations_triggered = false;
|
||||
if (!start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_MS) {
|
||||
if (!start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) {
|
||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
||||
|
||||
@@ -1919,7 +1934,7 @@ void Game::handleGameCompletedEvents() {
|
||||
|
||||
// Fin de celebraciones
|
||||
static bool end_celebrations_triggered = false;
|
||||
if (!end_celebrations_triggered && game_completed_timer_ >= END_CELEBRATIONS_MS) {
|
||||
if (!end_celebrations_triggered && game_completed_timer_ >= END_CELEBRATIONS_S) {
|
||||
for (auto &player : players_) {
|
||||
if (player->isCelebrating()) {
|
||||
player->setPlayingState(player->qualifiesForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
||||
|
||||
@@ -73,13 +73,13 @@ class Game {
|
||||
GAME_OVER, // Fin del juego
|
||||
};
|
||||
|
||||
// --- Constantes de tiempo (en milisegundos) ---
|
||||
static constexpr float HELP_COUNTER_MS = 16667.0f; // Contador de ayuda (1000 frames a 60fps)
|
||||
static constexpr float GAME_COMPLETED_START_FADE_MS = 8333.0f; // Inicio del fade al completar (500 frames)
|
||||
static constexpr float GAME_COMPLETED_END_MS = 11667.0f; // Fin del juego completado (700 frames)
|
||||
static constexpr float GAME_OVER_DURATION_MS = 5833.0f; // Duración game over (350 frames)
|
||||
static constexpr float TIME_STOPPED_DURATION_MS = 6000.0f; // Duración del tiempo detenido (360 frames)
|
||||
static constexpr int DEMO_FADE_PRE_DURATION_MS = 500; // Pre-duración del fade en modo demo
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos)
|
||||
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos)
|
||||
static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos)
|
||||
static constexpr float GAME_OVER_DURATION_S = 5.833f; // Duración game over (350 frames → segundos)
|
||||
static constexpr float TIME_STOPPED_DURATION_S = 6.0f; // Duración del tiempo detenido (360 frames → segundos)
|
||||
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; // Pre-duración del fade en modo demo
|
||||
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
|
||||
static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
|
||||
static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
|
||||
@@ -102,7 +102,7 @@ class Game {
|
||||
int item_coffee_machine_odds; // Probabilidad de aparición del objeto
|
||||
|
||||
Helper()
|
||||
: counter(HELP_COUNTER_MS),
|
||||
: counter(HELP_COUNTER_S * 1000), // Convertir a milisegundos para compatibilidad
|
||||
item_disk_odds(ITEM_POINTS_1_DISK_ODDS),
|
||||
item_gavina_odds(ITEM_POINTS_2_GAVINA_ODDS),
|
||||
item_pacmar_odds(ITEM_POINTS_3_PACMAR_ODDS),
|
||||
@@ -262,7 +262,7 @@ class Game {
|
||||
void freeSmartSprites(); // Libera memoria de sprites inteligentes
|
||||
|
||||
// --- Sprites por ruta (pathsprites) ---
|
||||
void updatePathSprites(); // Actualiza sprites que siguen rutas predefinidas
|
||||
void updatePathSprites(float deltaTime); // Actualiza sprites que siguen rutas predefinidas
|
||||
void renderPathSprites(); // Renderiza sprites animados por ruta
|
||||
void freePathSprites(); // Libera memoria de sprites por ruta
|
||||
void initPaths(); // Inicializa rutas predefinidas para animaciones
|
||||
|
||||
@@ -54,7 +54,8 @@ HiScoreTable::~HiScoreTable() {
|
||||
|
||||
// Actualiza las variables
|
||||
void HiScoreTable::update(float delta_time) {
|
||||
Screen::get()->update(); // Actualiza el objeto screen
|
||||
elapsed_time_ += delta_time; // Incrementa el tiempo transcurrido
|
||||
Screen::get()->update(); // Actualiza el objeto screen
|
||||
|
||||
updateSprites(delta_time); // Actualiza las posiciones de los sprites de texto
|
||||
background_->update(delta_time); // Actualiza el fondo
|
||||
@@ -72,9 +73,10 @@ void HiScoreTable::render() {
|
||||
SCREEN->start(); // Prepara para empezar a dibujar en la textura de juego
|
||||
SCREEN->clean(); // Limpia la pantalla
|
||||
|
||||
background_->render(); // Pinta el fondo
|
||||
view_area_.y = std::max(0.0F, param.game.height - counter_ + 100); // Establece la ventana del backbuffer
|
||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador
|
||||
background_->render(); // Pinta el fondo
|
||||
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir tiempo a equivalente frame para UI
|
||||
view_area_.y = std::max(0.0F, param.game.height - counter_equivalent + 100); // Establece la ventana del backbuffer
|
||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador
|
||||
fade_->render(); // Renderiza el fade
|
||||
|
||||
SCREEN->render(); // Vuelca el contenido del renderizador en pantalla
|
||||
@@ -117,7 +119,7 @@ void HiScoreTable::checkInput() {
|
||||
// Calcula el tiempo transcurrido desde el último frame
|
||||
float HiScoreTable::calculateDeltaTime() {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -217,15 +219,14 @@ void HiScoreTable::createSprites() {
|
||||
const int DEFAULT_POS_X = (backbuffer_width - ENTRY_WIDTH) / 2;
|
||||
const int POS_X = (i < 9) ? DEFAULT_POS_X : DEFAULT_POS_X - entry_text->getCharacterSize();
|
||||
const int POS_Y = (i * SPACE_BETWEEN_LINES) + FIRST_LINE + SPACE_BETWEEN_HEADER;
|
||||
constexpr int STEPS = 80;
|
||||
switch (ANIMATION) {
|
||||
case 0: // Ambos lados alternativamente
|
||||
{
|
||||
if (i % 2 == 0) {
|
||||
entry_names_.back()->addPath(-entry_names_.back()->getWidth(), POS_X, PathType::HORIZONTAL, POS_Y, STEPS, easeOutQuint);
|
||||
entry_names_.back()->addPath(-entry_names_.back()->getWidth(), POS_X, PathType::HORIZONTAL, POS_Y, ANIM_DURATION_S, easeOutQuint);
|
||||
entry_names_.back()->setPosition(-entry_names_.back()->getWidth(), 0);
|
||||
} else {
|
||||
entry_names_.back()->addPath(backbuffer_width, POS_X, PathType::HORIZONTAL, POS_Y, STEPS, easeOutQuint);
|
||||
entry_names_.back()->addPath(backbuffer_width, POS_X, PathType::HORIZONTAL, POS_Y, ANIM_DURATION_S, easeOutQuint);
|
||||
entry_names_.back()->setPosition(backbuffer_width, 0);
|
||||
}
|
||||
break;
|
||||
@@ -233,21 +234,21 @@ void HiScoreTable::createSprites() {
|
||||
|
||||
case 1: // Entran por la izquierda
|
||||
{
|
||||
entry_names_.back()->addPath(-entry_names_.back()->getWidth(), POS_X, PathType::HORIZONTAL, POS_Y, STEPS, easeOutQuint);
|
||||
entry_names_.back()->addPath(-entry_names_.back()->getWidth(), POS_X, PathType::HORIZONTAL, POS_Y, ANIM_DURATION_S, easeOutQuint);
|
||||
entry_names_.back()->setPosition(-entry_names_.back()->getWidth(), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // Entran por la derecha
|
||||
{
|
||||
entry_names_.back()->addPath(backbuffer_width, POS_X, PathType::HORIZONTAL, POS_Y, STEPS, easeOutQuint);
|
||||
entry_names_.back()->addPath(backbuffer_width, POS_X, PathType::HORIZONTAL, POS_Y, ANIM_DURATION_S, easeOutQuint);
|
||||
entry_names_.back()->setPosition(backbuffer_width, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: // Entran desde la parte inferior
|
||||
{
|
||||
entry_names_.back()->addPath(backbuffer_height, POS_Y, PathType::VERTICAL, POS_X, STEPS, easeOutQuint);
|
||||
entry_names_.back()->addPath(backbuffer_height, POS_Y, PathType::VERTICAL, POS_X, ANIM_DURATION_S, easeOutQuint);
|
||||
entry_names_.back()->setPosition(0, backbuffer_height);
|
||||
}
|
||||
|
||||
@@ -259,13 +260,13 @@ void HiScoreTable::createSprites() {
|
||||
|
||||
// Actualiza las posiciones de los sprites de texto
|
||||
void HiScoreTable::updateSprites(float delta_time) {
|
||||
constexpr int INIT_COUNTER = 190;
|
||||
const int COUNTER_BETWEEN_ENTRIES = 16;
|
||||
if (counter_ >= INIT_COUNTER) {
|
||||
const int COUNTER2 = counter_ - INIT_COUNTER;
|
||||
if (COUNTER2 % COUNTER_BETWEEN_ENTRIES == 0) {
|
||||
int index = COUNTER2 / COUNTER_BETWEEN_ENTRIES;
|
||||
if (index < static_cast<int>(entry_names_.size())) {
|
||||
if (elapsed_time_ >= INIT_DELAY_S) {
|
||||
const float elapsed_since_init = elapsed_time_ - INIT_DELAY_S;
|
||||
int index = static_cast<int>(elapsed_since_init / ENTRY_DELAY_S);
|
||||
if (index < static_cast<int>(entry_names_.size()) && index >= 0) {
|
||||
// Verificar si este índice debe activarse ahora
|
||||
float expected_time = index * ENTRY_DELAY_S;
|
||||
if (elapsed_since_init >= expected_time && elapsed_since_init < expected_time + delta_time) {
|
||||
entry_names_.at(index)->enable();
|
||||
}
|
||||
}
|
||||
@@ -290,7 +291,7 @@ void HiScoreTable::initFade() {
|
||||
void HiScoreTable::initBackground() {
|
||||
background_->setManualMode(true);
|
||||
background_->setPos(param.game.game_area.rect);
|
||||
background_->setCloudsSpeed(-0.1F);
|
||||
background_->setCloudsSpeed(CLOUDS_SPEED);
|
||||
|
||||
const int LUCKY = rand() % 3;
|
||||
switch (LUCKY) {
|
||||
@@ -355,7 +356,8 @@ void HiScoreTable::iniEntryColors() {
|
||||
|
||||
// Hace brillar los nombres de la tabla de records
|
||||
void HiScoreTable::glowEntryNames() {
|
||||
const Color ENTRY_COLOR = getEntryColor(counter_ / 5);
|
||||
int color_counter = static_cast<int>(elapsed_time_ * 60.0f / 5.0f); // Convertir tiempo a equivalente frame
|
||||
const Color ENTRY_COLOR = getEntryColor(color_counter);
|
||||
for (const auto &entry_index : Options::settings.glowing_entries) {
|
||||
if (entry_index != -1) {
|
||||
entry_names_.at(entry_index)->getTexture()->setColor(ENTRY_COLOR);
|
||||
@@ -365,14 +367,17 @@ void HiScoreTable::glowEntryNames() {
|
||||
|
||||
// Gestiona el contador
|
||||
void HiScoreTable::updateCounter() {
|
||||
++counter_;
|
||||
static bool background_changed = false;
|
||||
static bool fade_activated = false;
|
||||
|
||||
if (counter_ == 150) {
|
||||
if (elapsed_time_ >= BACKGROUND_CHANGE_S && !background_changed) {
|
||||
background_->setColor(background_fade_color_.DARKEN());
|
||||
background_->setAlpha(96);
|
||||
background_changed = true;
|
||||
}
|
||||
|
||||
if (counter_ == COUNTER_END) {
|
||||
if (elapsed_time_ >= COUNTER_END_S && !fade_activated) {
|
||||
fade_->activate();
|
||||
fade_activated = true;
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,13 @@ class HiScoreTable {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr Uint16 COUNTER_END = 800; // Valor final para el contador
|
||||
// --- Constantes (en segundos) ---
|
||||
static constexpr float COUNTER_END_S = 800.0f / 60.0f; // Tiempo final (≈13.33s)
|
||||
static constexpr float INIT_DELAY_S = 190.0f / 60.0f; // Retraso inicial (≈3.17s)
|
||||
static constexpr float ENTRY_DELAY_S = 16.0f / 60.0f; // Retraso entre entradas (≈0.27s)
|
||||
static constexpr float BACKGROUND_CHANGE_S = 150.0f / 60.0f; // Tiempo cambio fondo (≈2.5s)
|
||||
static constexpr float ANIM_DURATION_S = 80.0f / 60.0f; // Duración animación (≈1.33s)
|
||||
static constexpr float CLOUDS_SPEED = -6.0f; // Velocidad nubes (pixels/s)
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
@@ -44,7 +49,7 @@ class HiScoreTable {
|
||||
std::vector<Path> paths_; // Vector con los recorridos precalculados
|
||||
|
||||
// --- Variables ---
|
||||
Uint16 counter_ = 0; // Contador
|
||||
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos)
|
||||
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||
SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla
|
||||
Fade::Mode fade_mode_; // Modo de fade a utilizar
|
||||
|
||||
@@ -88,24 +88,24 @@ void Instructions::iniSprites() {
|
||||
void Instructions::updateSprites() {
|
||||
SDL_FRect src_rect = {0, 0, param.game.item_size, param.game.item_size};
|
||||
|
||||
// Disquito
|
||||
src_rect.y = param.game.item_size * (((counter_ + 12) / 36) % 2);
|
||||
// Disquito (desplazamiento 12/60 = 0.2s)
|
||||
src_rect.y = param.game.item_size * (static_cast<int>((elapsed_time_ + 0.2f) / SPRITE_ANIMATION_CYCLE_S) % 2);
|
||||
sprites_[0]->setSpriteClip(src_rect);
|
||||
|
||||
// Gavina
|
||||
src_rect.y = param.game.item_size * (((counter_ + 9) / 36) % 2);
|
||||
// Gavina (desplazamiento 9/60 = 0.15s)
|
||||
src_rect.y = param.game.item_size * (static_cast<int>((elapsed_time_ + 0.15f) / SPRITE_ANIMATION_CYCLE_S) % 2);
|
||||
sprites_[1]->setSpriteClip(src_rect);
|
||||
|
||||
// Pacmar
|
||||
src_rect.y = param.game.item_size * (((counter_ + 6) / 36) % 2);
|
||||
// Pacmar (desplazamiento 6/60 = 0.1s)
|
||||
src_rect.y = param.game.item_size * (static_cast<int>((elapsed_time_ + 0.1f) / SPRITE_ANIMATION_CYCLE_S) % 2);
|
||||
sprites_[2]->setSpriteClip(src_rect);
|
||||
|
||||
// Time Stopper
|
||||
src_rect.y = param.game.item_size * (((counter_ + 3) / 36) % 2);
|
||||
// Time Stopper (desplazamiento 3/60 = 0.05s)
|
||||
src_rect.y = param.game.item_size * (static_cast<int>((elapsed_time_ + 0.05f) / SPRITE_ANIMATION_CYCLE_S) % 2);
|
||||
sprites_[3]->setSpriteClip(src_rect);
|
||||
|
||||
// Coffee
|
||||
src_rect.y = param.game.item_size * (((counter_ + 0) / 36) % 2);
|
||||
// Coffee (sin desplazamiento)
|
||||
src_rect.y = param.game.item_size * (static_cast<int>(elapsed_time_ / SPRITE_ANIMATION_CYCLE_S) % 2);
|
||||
sprites_[4]->setSpriteClip(src_rect);
|
||||
}
|
||||
|
||||
@@ -205,11 +205,11 @@ void Instructions::fillBackbuffer() {
|
||||
|
||||
// Actualiza las variables
|
||||
void Instructions::update(float delta_time) {
|
||||
Screen::get()->update(); // Actualiza el objeto screen
|
||||
elapsed_time_ += delta_time; // Incrementa el tiempo transcurrido
|
||||
Screen::get()->update(); // Actualiza el objeto screen
|
||||
|
||||
counter_++; // Incrementa el contador
|
||||
updateSprites(); // Actualiza los sprites
|
||||
updateBackbuffer(); // Gestiona la textura con los graficos
|
||||
updateBackbuffer(delta_time); // Gestiona la textura con los graficos
|
||||
tiled_bg_->update(delta_time); // Actualiza el mosaico de fondo
|
||||
fade_->update(delta_time); // Actualiza el objeto "fade"
|
||||
fillBackbuffer(); // Rellena el backbuffer
|
||||
@@ -255,7 +255,7 @@ void Instructions::checkInput() {
|
||||
// Calcula el tiempo transcurrido desde el último frame
|
||||
float Instructions::calculateDeltaTime() {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -324,23 +324,27 @@ void Instructions::renderLines(SDL_Renderer *renderer, SDL_Texture *texture, con
|
||||
}
|
||||
|
||||
// Gestiona la textura con los graficos
|
||||
void Instructions::updateBackbuffer() {
|
||||
// Establece la ventana del backbuffer
|
||||
view_.y = std::max(0.0F, param.game.height - counter_ + 100);
|
||||
void Instructions::updateBackbuffer(float delta_time) {
|
||||
// Establece la ventana del backbuffer (convertir elapsed_time_ a equivalente de counter)
|
||||
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir segundos a equivalente frame para UI
|
||||
view_.y = std::max(0.0F, param.game.height - counter_equivalent + 100);
|
||||
|
||||
// Verifica si view_.y == 0 y gestiona el temporizador
|
||||
if (view_.y == 0) {
|
||||
if (!start_delay_triggered_) {
|
||||
// Activa el temporizador si no ha sido activado
|
||||
start_delay_triggered_ = true;
|
||||
start_delay_time_ = SDL_GetTicks();
|
||||
} else if (SDL_GetTicks() - start_delay_time_ >= 4000) {
|
||||
// Han pasado tres segundos, mover líneas
|
||||
all_lines_off_screen_ = moveLines(lines_, 320, 1.0F, 5);
|
||||
start_delay_timer_ = 0.0f;
|
||||
} else {
|
||||
start_delay_timer_ += delta_time;
|
||||
if (start_delay_timer_ >= START_DELAY_S) {
|
||||
// Han pasado los segundos de retraso, mover líneas
|
||||
all_lines_off_screen_ = moveLines(lines_, 320, LINE_MOVE_DURATION_S, static_cast<Uint32>(LINE_START_DELAY_MS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba si el contador ha llegado al final
|
||||
// Comprueba si todas las líneas han terminado
|
||||
if (all_lines_off_screen_) {
|
||||
Section::name = Section::Name::TITLE;
|
||||
Section::options = Section::Options::TITLE_1;
|
||||
|
||||
@@ -50,6 +50,12 @@ class Instructions {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float SPRITE_ANIMATION_CYCLE_S = 36.0f / 60.0f; // Ciclo de animación sprites (≈0.6s)
|
||||
static constexpr float START_DELAY_S = 4.0f; // Retraso antes de mover líneas (4s)
|
||||
static constexpr float LINE_MOVE_DURATION_S = 1.0f; // Duración movimiento líneas (1s)
|
||||
static constexpr float LINE_START_DELAY_MS = 5.0f; // Retraso entre líneas (5ms)
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
SDL_Texture *texture_; // Textura fija con el texto
|
||||
@@ -62,14 +68,14 @@ class Instructions {
|
||||
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
|
||||
|
||||
// --- Variables ---
|
||||
int counter_ = 0; // Contador para manejar el progreso en la pantalla de instrucciones
|
||||
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos)
|
||||
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||
SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla
|
||||
SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
|
||||
float item_space_ = 2.0; // Espacio entre los items en pantalla
|
||||
std::vector<Line> lines_; // Vector que contiene las líneas animadas en la pantalla
|
||||
bool all_lines_off_screen_ = false; // Indica si todas las líneas han salido de la pantalla
|
||||
Uint32 start_delay_time_ = 0; // Tiempo de inicio del retraso para mover las líneas
|
||||
float start_delay_timer_ = 0.0f; // Timer para retraso antes de mover líneas (segundos)
|
||||
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
|
||||
|
||||
// --- Métodos internos ---
|
||||
@@ -84,6 +90,6 @@ class Instructions {
|
||||
static auto initializeLines(int height) -> std::vector<Line>; // Inicializa las líneas animadas
|
||||
static auto moveLines(std::vector<Line> &lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas (ya usa tiempo real)
|
||||
static void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
|
||||
void updateBackbuffer(); // Gestiona la textura con los gráficos
|
||||
void updateBackbuffer(float delta_time); // Gestiona la textura con los gráficos
|
||||
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
|
||||
};
|
||||
@@ -39,7 +39,7 @@ Intro::Intro()
|
||||
initTexts();
|
||||
|
||||
// Configura el fondo
|
||||
tiled_bg_->setSpeed(0.3F);
|
||||
tiled_bg_->setSpeed(TILED_BG_SPEED);
|
||||
tiled_bg_->setColor(bg_color_);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ void Intro::updateScene5() {
|
||||
// Acaba la ultima imagen
|
||||
if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished()) {
|
||||
state_ = State::POST;
|
||||
state_start_time_ = SDL_GetTicks();
|
||||
state_start_time_ = SDL_GetTicks() / 1000.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ void Intro::render() {
|
||||
// Calcula el tiempo transcurrido desde el último frame
|
||||
float Intro::calculateDeltaTime() {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -338,13 +338,13 @@ void Intro::initSprites() {
|
||||
const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2);
|
||||
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
|
||||
|
||||
card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0);
|
||||
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0);
|
||||
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0);
|
||||
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0);
|
||||
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0);
|
||||
card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f);
|
||||
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f);
|
||||
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f);
|
||||
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f);
|
||||
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f);
|
||||
card_sprites_.at(5)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG);
|
||||
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0);
|
||||
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f);
|
||||
|
||||
// Constantes
|
||||
const float DESP = SHADOW_OFFSET;
|
||||
@@ -389,13 +389,13 @@ void Intro::initSprites() {
|
||||
const float S_X_DEST = X_DEST + DESP;
|
||||
const float S_Y_DEST = Y_DEST + DESP;
|
||||
|
||||
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0);
|
||||
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0);
|
||||
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0);
|
||||
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0);
|
||||
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0);
|
||||
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f);
|
||||
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f);
|
||||
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f);
|
||||
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f);
|
||||
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f);
|
||||
shadow_sprites_.at(5)->addPath(param.game.width, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG);
|
||||
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0);
|
||||
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f);
|
||||
}
|
||||
|
||||
// Inicializa los textos
|
||||
@@ -407,45 +407,45 @@ void Intro::initTexts() {
|
||||
writer->setPosY(param.game.height - param.intro.text_distance_from_bottom);
|
||||
writer->setKerning(TEXT_KERNING);
|
||||
writer->setEnabled(false);
|
||||
writer->setFinishedTimerMs(TEXT_DISPLAY_DURATION_MS);
|
||||
writer->setFinishedTimerS(TEXT_DISPLAY_DURATION_S);
|
||||
texts_.push_back(std::move(writer));
|
||||
}
|
||||
|
||||
// Un dia qualsevol de l'any 2000
|
||||
texts_.at(0)->setCaption(Lang::getText("[INTRO] 1"));
|
||||
texts_.at(0)->setSpeed(TEXT_SPEED_NORMAL);
|
||||
texts_.at(0)->setSpeedS(TEXT_SPEED_NORMAL);
|
||||
|
||||
// Tot esta tranquil a la UPV
|
||||
texts_.at(1)->setCaption(Lang::getText("[INTRO] 2"));
|
||||
texts_.at(1)->setSpeed(TEXT_SPEED_NORMAL);
|
||||
texts_.at(1)->setSpeedS(TEXT_SPEED_NORMAL);
|
||||
|
||||
// Fins que un desaprensiu...
|
||||
texts_.at(2)->setCaption(Lang::getText("[INTRO] 3"));
|
||||
texts_.at(2)->setSpeed(TEXT_SPEED_FAST);
|
||||
texts_.at(2)->setSpeedS(TEXT_SPEED_FAST);
|
||||
|
||||
// HEY! ME ANE A FERME UN CORTAET...
|
||||
texts_.at(3)->setCaption(Lang::getText("[INTRO] 4"));
|
||||
texts_.at(3)->setSpeed(TEXT_SPEED_NORMAL);
|
||||
texts_.at(3)->setSpeedS(TEXT_SPEED_NORMAL);
|
||||
|
||||
// UAAAAAAAAAAAAA!!!
|
||||
texts_.at(4)->setCaption(Lang::getText("[INTRO] 5"));
|
||||
texts_.at(4)->setSpeed(TEXT_SPEED_VERY_SLOW);
|
||||
texts_.at(4)->setSpeedS(TEXT_SPEED_VERY_SLOW);
|
||||
|
||||
// Espera un moment...
|
||||
texts_.at(5)->setCaption(Lang::getText("[INTRO] 6"));
|
||||
texts_.at(5)->setSpeed(TEXT_SPEED_VERY_FAST);
|
||||
texts_.at(5)->setSpeedS(TEXT_SPEED_VERY_FAST);
|
||||
|
||||
// Si resulta que no tinc solt!
|
||||
texts_.at(6)->setCaption(Lang::getText("[INTRO] 7"));
|
||||
texts_.at(6)->setSpeed(TEXT_SPEED_SLOW);
|
||||
texts_.at(6)->setSpeedS(TEXT_SPEED_SLOW);
|
||||
|
||||
// MERDA DE MAQUINA!
|
||||
texts_.at(7)->setCaption(Lang::getText("[INTRO] 8"));
|
||||
texts_.at(7)->setSpeed(TEXT_SPEED_MEDIUM_SLOW);
|
||||
texts_.at(7)->setSpeedS(TEXT_SPEED_MEDIUM_SLOW);
|
||||
|
||||
// Blop... blop... blop...
|
||||
texts_.at(8)->setCaption(Lang::getText("[INTRO] 9"));
|
||||
texts_.at(8)->setSpeed(TEXT_SPEED_ULTRA_FAST);
|
||||
texts_.at(8)->setSpeedS(TEXT_SPEED_ULTRA_FAST);
|
||||
|
||||
for (auto &text : texts_) {
|
||||
text->center(param.game.game_area.center_x);
|
||||
@@ -466,7 +466,7 @@ void Intro::updateSprites(float delta_time) {
|
||||
// Actualiza los textos
|
||||
void Intro::updateTexts(float delta_time) {
|
||||
for (auto &text : texts_) {
|
||||
text->update(delta_time);
|
||||
text->updateS(delta_time); // Usar updateS para delta_time en segundos
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,12 +485,12 @@ void Intro::renderTexts() {
|
||||
|
||||
// Actualiza el estado POST
|
||||
void Intro::updatePostState() {
|
||||
const Uint32 ELAPSED_TIME = SDL_GetTicks() - state_start_time_;
|
||||
const float ELAPSED_TIME = (SDL_GetTicks() / 1000.0f) - state_start_time_;
|
||||
|
||||
switch (post_state_) {
|
||||
case PostState::STOP_BG:
|
||||
// EVENTO: Detiene el fondo después del tiempo especificado
|
||||
if (ELAPSED_TIME >= POST_BG_STOP_DELAY_MS) {
|
||||
if (ELAPSED_TIME >= POST_BG_STOP_DELAY_S) {
|
||||
tiled_bg_->stopGracefully();
|
||||
|
||||
if (!bg_color_.IS_EQUAL_TO(param.title.bg_color)) {
|
||||
@@ -503,13 +503,13 @@ void Intro::updatePostState() {
|
||||
// Cambia de estado si el fondo se ha detenido y recuperado el color
|
||||
if (tiled_bg_->isStopped() && bg_color_.IS_EQUAL_TO(param.title.bg_color)) {
|
||||
post_state_ = PostState::END;
|
||||
state_start_time_ = SDL_GetTicks();
|
||||
state_start_time_ = SDL_GetTicks() / 1000.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case PostState::END:
|
||||
// Finaliza la intro después del tiempo especificado
|
||||
if (ELAPSED_TIME >= POST_END_DELAY_MS) {
|
||||
if (ELAPSED_TIME >= POST_END_DELAY_S) {
|
||||
Audio::get()->stopMusic();
|
||||
Section::name = Section::Name::TITLE;
|
||||
Section::options = Section::Options::TITLE_1;
|
||||
|
||||
@@ -37,34 +37,36 @@ class Intro {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Constantes de tiempo (en milisegundos) ---
|
||||
static constexpr float TEXT_DISPLAY_DURATION_MS = 3000.0f; // Duración de visualización de texto (180 frames a 60fps)
|
||||
static constexpr Uint32 POST_BG_STOP_DELAY_MS = 1000; // Retraso antes de detener el fondo
|
||||
static constexpr Uint32 POST_END_DELAY_MS = 1000; // Retraso antes de finalizar intro
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0f; // Duración de visualización de texto (180 frames a 60fps)
|
||||
static constexpr float POST_BG_STOP_DELAY_S = 1.0f; // Retraso antes de detener el fondo
|
||||
static constexpr float POST_END_DELAY_S = 1.0f; // Retraso antes de finalizar intro
|
||||
|
||||
// --- Constantes de layout ---
|
||||
static constexpr float CARD_BORDER_SIZE = 2.0f; // Tamaño del borde de tarjetas
|
||||
static constexpr float SHADOW_OFFSET = 8.0f; // Desplazamiento de sombra
|
||||
static constexpr float TILED_BG_SPEED = 18.0f; // Velocidad del fondo mosaico (pixels/segundo)
|
||||
static constexpr int TEXT_KERNING = -2; // Espaciado entre caracteres
|
||||
|
||||
// --- Constantes de velocidades de texto ---
|
||||
static constexpr int TEXT_SPEED_NORMAL = 8; // Velocidad normal de escritura
|
||||
static constexpr int TEXT_SPEED_FAST = 12; // Velocidad rápida
|
||||
static constexpr int TEXT_SPEED_VERY_SLOW = 1; // Velocidad muy lenta (grito)
|
||||
static constexpr int TEXT_SPEED_VERY_FAST = 16; // Velocidad muy rápida
|
||||
static constexpr int TEXT_SPEED_SLOW = 2; // Velocidad lenta
|
||||
static constexpr int TEXT_SPEED_MEDIUM_SLOW = 3; // Velocidad medio-lenta
|
||||
static constexpr int TEXT_SPEED_ULTRA_FAST = 20; // Velocidad ultra rápida
|
||||
// --- Constantes de velocidades de texto (segundos entre caracteres) ---
|
||||
static constexpr float TEXT_SPEED_NORMAL = 0.133f; // Velocidad normal (8 frames * 16.67ms = 133ms)
|
||||
static constexpr float TEXT_SPEED_FAST = 0.2f; // Velocidad rápida (12 frames * 16.67ms = 200ms)
|
||||
static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167f; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms)
|
||||
static constexpr float TEXT_SPEED_VERY_FAST = 0.267f; // Velocidad muy rápida (16 frames * 16.67ms = 267ms)
|
||||
static constexpr float TEXT_SPEED_SLOW = 0.033f; // Velocidad lenta (2 frames * 16.67ms = 33ms)
|
||||
static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05f; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms)
|
||||
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333f; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms)
|
||||
|
||||
// --- Constantes de animaciones de tarjetas (duraciones en ms) ---
|
||||
static constexpr int CARD_ANIM_DURATION_NORMAL = 100; // Duración estándar (100ms)
|
||||
static constexpr int CARD_ANIM_DURATION_FAST = 40; // Duración rápida (40ms)
|
||||
static constexpr int CARD_ANIM_DURATION_MEDIUM = 70; // Duración media (70ms)
|
||||
static constexpr int CARD_ANIM_DURATION_SHORT = 80; // Duración corta (80ms)
|
||||
static constexpr int CARD_ANIM_DURATION_SLOW = 250; // Duración lenta (250ms)
|
||||
static constexpr int CARD_ANIM_DURATION_VERY_SLOW = 300; // Duración muy lenta (300ms)
|
||||
static constexpr int CARD_ANIM_DELAY_LONG = 450; // Retraso largo antes de animación
|
||||
static constexpr float CARD_OFFSET_MARGIN = 10.0f; // Margen fuera de pantalla
|
||||
// --- Constantes de animaciones de tarjetas (duraciones en segundos) ---
|
||||
static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0f / 60.0f; // ≈ 1.6667 s
|
||||
static constexpr float CARD_ANIM_DURATION_FAST = 40.0f / 60.0f; // ≈ 0.6667 s
|
||||
static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0f / 60.0f; // ≈ 1.1667 s
|
||||
static constexpr float CARD_ANIM_DURATION_SHORT = 80.0f / 60.0f; // ≈ 1.3333 s
|
||||
static constexpr float CARD_ANIM_DURATION_SLOW = 250.0f / 60.0f; // ≈ 4.1667 s
|
||||
static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0f / 60.0f; // ≈ 5.0000 s
|
||||
|
||||
static constexpr float CARD_ANIM_DELAY_LONG = 0.45f; // Retraso largo antes de animación
|
||||
static constexpr float CARD_OFFSET_MARGIN = 10.0f; // Margen fuera de pantalla
|
||||
|
||||
// --- Estados internos ---
|
||||
enum class State {
|
||||
@@ -88,7 +90,7 @@ class Intro {
|
||||
int scene_ = 0; // Indica qué escena está activa
|
||||
State state_ = State::SCENES; // Estado principal de la intro
|
||||
PostState post_state_ = PostState::STOP_BG; // Estado POST
|
||||
Uint32 state_start_time_; // Tiempo de inicio del estado actual
|
||||
float state_start_time_; // Tiempo de inicio del estado actual (segundos)
|
||||
Color bg_color_ = param.intro.bg_color; // Color de fondo
|
||||
|
||||
// --- Métodos internos ---
|
||||
|
||||
@@ -82,7 +82,7 @@ void Logo::checkInput() {
|
||||
void Logo::handleSound() {
|
||||
static bool sound_triggered = false;
|
||||
|
||||
if (!sound_triggered && elapsed_time_ms_ >= SOUND_TRIGGER_TIME_MS) {
|
||||
if (!sound_triggered && elapsed_time_s_ >= SOUND_TRIGGER_TIME_S) {
|
||||
Audio::get()->playSound("logo.wav");
|
||||
sound_triggered = true;
|
||||
}
|
||||
@@ -90,8 +90,8 @@ void Logo::handleSound() {
|
||||
|
||||
// Gestiona el logo de JAILGAMES
|
||||
void Logo::updateJAILGAMES(float delta_time) {
|
||||
if (elapsed_time_ms_ > SOUND_TRIGGER_TIME_MS) {
|
||||
const float PIXELS_TO_MOVE = LOGO_SPEED_PX_PER_MS * delta_time;
|
||||
if (elapsed_time_s_ > SOUND_TRIGGER_TIME_S) {
|
||||
const float PIXELS_TO_MOVE = LOGO_SPEED_PX_PER_S * delta_time;
|
||||
|
||||
for (size_t i = 0; i < jail_sprite_.size(); ++i) {
|
||||
if (jail_sprite_[i]->getX() != dest_.x) {
|
||||
@@ -111,7 +111,7 @@ void Logo::updateJAILGAMES(float delta_time) {
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado el logo
|
||||
if (elapsed_time_ms_ >= END_LOGO_TIME_MS + POST_LOGO_DURATION_MS) {
|
||||
if (elapsed_time_s_ >= END_LOGO_TIME_S + POST_LOGO_DURATION_S) {
|
||||
Section::name = Section::Name::INTRO;
|
||||
}
|
||||
}
|
||||
@@ -120,16 +120,16 @@ void Logo::updateJAILGAMES(float delta_time) {
|
||||
void Logo::updateTextureColors(float delta_time) {
|
||||
// Manejo de 'sinceTexture'
|
||||
for (int i = 0; i <= MAX_SINCE_COLOR_INDEX; ++i) {
|
||||
const float target_time = SHOW_SINCE_SPRITE_TIME_MS + COLOR_CHANGE_INTERVAL_MS * i;
|
||||
if (elapsed_time_ms_ >= target_time && elapsed_time_ms_ - delta_time < target_time) {
|
||||
const float target_time = SHOW_SINCE_SPRITE_TIME_S + COLOR_CHANGE_INTERVAL_S * i;
|
||||
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) {
|
||||
since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b);
|
||||
}
|
||||
}
|
||||
|
||||
// Manejo de 'jailTexture' y 'sinceTexture' en el fade
|
||||
for (int i = 0; i <= MAX_FADE_COLOR_INDEX; ++i) {
|
||||
const float target_time = INIT_FADE_TIME_MS + COLOR_CHANGE_INTERVAL_MS * i;
|
||||
if (elapsed_time_ms_ >= target_time && elapsed_time_ms_ - delta_time < target_time) {
|
||||
const float target_time = INIT_FADE_TIME_S + COLOR_CHANGE_INTERVAL_S * i;
|
||||
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) {
|
||||
jail_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
|
||||
since_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
|
||||
}
|
||||
@@ -138,7 +138,7 @@ void Logo::updateTextureColors(float delta_time) {
|
||||
|
||||
// Actualiza las variables
|
||||
void Logo::update(float delta_time) {
|
||||
elapsed_time_ms_ += delta_time; // Acumula el tiempo transcurrido
|
||||
elapsed_time_s_ += delta_time; // Acumula el tiempo transcurrido
|
||||
|
||||
Screen::get()->update(); // Actualiza el objeto screen
|
||||
Audio::update(); // Actualiza el objeto audio
|
||||
@@ -163,7 +163,7 @@ void Logo::render() {
|
||||
// Calcula el tiempo transcurrido desde el último frame
|
||||
float Logo::calculateDeltaTime() {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -189,7 +189,7 @@ void Logo::renderJAILGAMES() {
|
||||
sprite->render();
|
||||
}
|
||||
|
||||
if (elapsed_time_ms_ >= SHOW_SINCE_SPRITE_TIME_MS) {
|
||||
if (elapsed_time_s_ >= SHOW_SINCE_SPRITE_TIME_S) {
|
||||
since_sprite_->render();
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class Texture;
|
||||
// • Transición temporal: duración controlada con paso automático al siguiente estado
|
||||
// • Sistema delta-time: animaciones suaves independientes del framerate
|
||||
//
|
||||
// La clase utiliza un sistema de tiempo basado en milisegundos para garantizar
|
||||
// La clase utiliza un sistema de tiempo basado en segundos para garantizar
|
||||
// consistencia visual en diferentes velocidades de procesamiento.
|
||||
|
||||
class Logo {
|
||||
@@ -35,14 +35,14 @@ class Logo {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Constantes de tiempo (en milisegundos) ---
|
||||
static constexpr float SOUND_TRIGGER_TIME_MS = 500.0f; // Tiempo para activar el sonido del logo
|
||||
static constexpr float SHOW_SINCE_SPRITE_TIME_MS = 1167.0f; // Tiempo para mostrar el sprite "SINCE 1998"
|
||||
static constexpr float INIT_FADE_TIME_MS = 5000.0f; // Tiempo de inicio del fade a negro
|
||||
static constexpr float END_LOGO_TIME_MS = 6668.0f; // Tiempo de finalización del logo
|
||||
static constexpr float POST_LOGO_DURATION_MS = 333.0f; // Duración adicional después del fade
|
||||
static constexpr float LOGO_SPEED_PX_PER_MS = 8.0f / 16.67f; // Velocidad de desplazamiento (píxeles por ms)
|
||||
static constexpr float COLOR_CHANGE_INTERVAL_MS = 66.7f; // Intervalo entre cambios de color (~4 frames a 60fps)
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float SOUND_TRIGGER_TIME_S = 0.5f; // Tiempo para activar el sonido del logo
|
||||
static constexpr float SHOW_SINCE_SPRITE_TIME_S = 1.167f; // Tiempo para mostrar el sprite "SINCE 1998"
|
||||
static constexpr float INIT_FADE_TIME_S = 5.0f; // Tiempo de inicio del fade a negro
|
||||
static constexpr float END_LOGO_TIME_S = 6.668f; // Tiempo de finalización del logo
|
||||
static constexpr float POST_LOGO_DURATION_S = 0.333f; // Duración adicional después del fade
|
||||
static constexpr float LOGO_SPEED_PX_PER_S = 480.0f; // Velocidad de desplazamiento (píxeles por segundo) - 8.0f/16.67f*1000
|
||||
static constexpr float COLOR_CHANGE_INTERVAL_S = 0.0667f; // Intervalo entre cambios de color (~4 frames a 60fps)
|
||||
|
||||
// --- Constantes de layout ---
|
||||
static constexpr int SINCE_SPRITE_Y_OFFSET = 83; // Posición Y base del sprite "Since 1998"
|
||||
@@ -73,7 +73,7 @@ class Logo {
|
||||
|
||||
// --- Variables ---
|
||||
std::vector<Color> color_; // Vector con los colores para el fade
|
||||
float elapsed_time_ms_ = 0.0f; // Tiempo transcurrido en milisegundos
|
||||
float elapsed_time_s_ = 0.0f; // Tiempo transcurrido en segundos
|
||||
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||
SDL_FPoint dest_; // Posición donde dibujar el logo
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ Title::Title()
|
||||
num_controllers_(Input::get()->getNumGamepads()) {
|
||||
// Configura objetos
|
||||
tiled_bg_->setColor(param.title.bg_color);
|
||||
tiled_bg_->setSpeed(60.0F); // Set appropriate speed for seconds-based deltaTime
|
||||
game_logo_->enable();
|
||||
mini_logo_sprite_->setX(param.game.game_area.center_x - (mini_logo_sprite_->getWidth() / 2));
|
||||
fade_->setColor(param.fade.color);
|
||||
@@ -82,7 +83,7 @@ void Title::update(float deltaTime) {
|
||||
Screen::get()->update();
|
||||
updateFade();
|
||||
updateState(deltaTime);
|
||||
updateStartPrompt();
|
||||
updateStartPrompt(deltaTime);
|
||||
|
||||
for (auto& player : players_) {
|
||||
player->update(deltaTime);
|
||||
@@ -94,7 +95,7 @@ void Title::update(float deltaTime) {
|
||||
// Calcula el tiempo transcurrido desde el último frame
|
||||
float Title::calculateDeltaTime() {
|
||||
const Uint64 current_time = SDL_GetTicks();
|
||||
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convert ms to seconds
|
||||
last_time_ = current_time;
|
||||
return delta_time;
|
||||
}
|
||||
@@ -403,7 +404,7 @@ void Title::updateState(float deltaTime) {
|
||||
case State::START_HAS_BEEN_PRESSED: {
|
||||
counter_time_ += deltaTime;
|
||||
|
||||
if (counter_time_ >= START_PRESSED_DELAY_MS) {
|
||||
if (counter_time_ >= START_PRESSED_DELAY_S) {
|
||||
fade_->activate();
|
||||
}
|
||||
break;
|
||||
@@ -414,23 +415,38 @@ void Title::updateState(float deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
void Title::updateStartPrompt() {
|
||||
Uint32 time_ms = SDL_GetTicks();
|
||||
void Title::updateStartPrompt(float deltaTime) {
|
||||
blink_accumulator_ += deltaTime;
|
||||
|
||||
bool condition_met = false;
|
||||
float period = 0.0f;
|
||||
float on_time = 0.0f;
|
||||
|
||||
switch (state_) {
|
||||
case State::LOGO_FINISHED:
|
||||
condition_met = (time_ms % LOGO_BLINK_PERIOD_MS) >= (LOGO_BLINK_PERIOD_MS - LOGO_BLINK_ON_TIME_MS);
|
||||
period = LOGO_BLINK_PERIOD_S;
|
||||
on_time = LOGO_BLINK_ON_TIME_S;
|
||||
break;
|
||||
|
||||
case State::START_HAS_BEEN_PRESSED:
|
||||
condition_met = (time_ms % START_BLINK_PERIOD_MS) >= (START_BLINK_PERIOD_MS - START_BLINK_ON_TIME_MS);
|
||||
period = START_BLINK_PERIOD_S;
|
||||
on_time = START_BLINK_ON_TIME_S;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (period > 0.0f) {
|
||||
// Reset accumulator when it exceeds the period
|
||||
if (blink_accumulator_ >= period) {
|
||||
blink_accumulator_ -= period;
|
||||
}
|
||||
|
||||
// Check if we're in the "on" time of the blink cycle
|
||||
condition_met = blink_accumulator_ >= (period - on_time);
|
||||
}
|
||||
|
||||
should_render_start_prompt_ = condition_met;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ struct Gamepad;
|
||||
// • Timeouts automáticos: transición automática si no hay interacción
|
||||
// • Debug de colores: herramientas de depuración para ajustes visuales
|
||||
//
|
||||
// La clase utiliza un sistema de tiempo basado en milisegundos para garantizar
|
||||
// La clase utiliza un sistema de tiempo basado en segundos para garantizar
|
||||
// comportamiento consistente independientemente del framerate.
|
||||
class Title {
|
||||
public:
|
||||
@@ -45,16 +45,16 @@ class Title {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Constantes de tiempo (en milisegundos) ---
|
||||
static constexpr float START_PRESSED_DELAY_MS = 1666.67f; // Tiempo antes de fade tras pulsar start (100 frames a 60fps)
|
||||
static constexpr int MUSIC_FADE_OUT_LONG_MS = 1500; // Fade out largo de música
|
||||
static constexpr int MUSIC_FADE_OUT_SHORT_MS = 300; // Fade out corto de música
|
||||
// --- Constantes de tiempo (en segundos) ---
|
||||
static constexpr float START_PRESSED_DELAY_S = 1666.67f / 1000.0f; // Tiempo antes de fade tras pulsar start (100 frames a 60fps)
|
||||
static constexpr int MUSIC_FADE_OUT_LONG_MS = 1500; // Fade out largo de música
|
||||
static constexpr int MUSIC_FADE_OUT_SHORT_MS = 300; // Fade out corto de música
|
||||
|
||||
// --- Constantes de parpadeo ---
|
||||
static constexpr Uint32 LOGO_BLINK_PERIOD_MS = 833; // Período de parpadeo del logo
|
||||
static constexpr Uint32 LOGO_BLINK_ON_TIME_MS = 583; // Tiempo encendido del logo (833-250)
|
||||
static constexpr Uint32 START_BLINK_PERIOD_MS = 167; // Período de parpadeo del start
|
||||
static constexpr Uint32 START_BLINK_ON_TIME_MS = 83; // Tiempo encendido del start (167-83)
|
||||
// --- Constantes de parpadeo (en segundos) ---
|
||||
static constexpr float LOGO_BLINK_PERIOD_S = 833.0f / 1000.0f; // Período de parpadeo del logo (833ms)
|
||||
static constexpr float LOGO_BLINK_ON_TIME_S = 583.0f / 1000.0f; // Tiempo encendido del logo (583ms)
|
||||
static constexpr float START_BLINK_PERIOD_S = 167.0f / 1000.0f; // Período de parpadeo del start (167ms)
|
||||
static constexpr float START_BLINK_ON_TIME_S = 83.0f / 1000.0f; // Tiempo encendido del start (83ms)
|
||||
|
||||
// --- Constantes de layout ---
|
||||
static constexpr int MINI_LOGO_Y_DIVISOR = 5; // Divisor para posición Y del mini logo
|
||||
@@ -92,7 +92,8 @@ class Title {
|
||||
Section::Options selection_ = Section::Options::TITLE_TIME_OUT; // Opción elegida en el título
|
||||
State state_; // Estado actual de la sección
|
||||
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||
float counter_time_ = 0.0f; // Temporizador para la pantalla de título (en milisegundos)
|
||||
float counter_time_ = 0.0f; // Temporizador para la pantalla de título (en segundos)
|
||||
float blink_accumulator_ = 0.0f; // Acumulador para el parpadeo (en segundos)
|
||||
int num_controllers_; // Número de mandos conectados
|
||||
bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY
|
||||
bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1
|
||||
@@ -127,7 +128,7 @@ class Title {
|
||||
// --- Visualización / Renderizado ---
|
||||
void render(); // Dibuja el objeto en pantalla
|
||||
void updateFade(); // Actualiza el efecto de fundido (fade in/out)
|
||||
void updateStartPrompt(); // Actualiza el mensaje de "Pulsa Start"
|
||||
void updateStartPrompt(float deltaTime); // Actualiza el mensaje de "Pulsa Start"
|
||||
void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla
|
||||
void renderCopyright(); // Dibuja el aviso de copyright
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ void SmartSprite::update(float deltaTime) {
|
||||
if (enabled_) {
|
||||
MovingSprite::update(deltaTime);
|
||||
checkMove();
|
||||
checkFinished();
|
||||
checkFinished(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,16 +71,19 @@ void SmartSprite::checkMove() {
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado
|
||||
void SmartSprite::checkFinished() {
|
||||
// Comprueba si ha terminado (time-based)
|
||||
void SmartSprite::checkFinished(float deltaTime) {
|
||||
// Comprueba si ha llegado a su destino
|
||||
on_destination_ = (getPosX() == dest_x_ && getPosY() == dest_y_);
|
||||
|
||||
if (on_destination_) {
|
||||
if (finished_counter_ == 0) {
|
||||
if (finished_delay_ms_ == 0.0f) {
|
||||
finished_ = true;
|
||||
} else {
|
||||
--finished_counter_;
|
||||
finished_timer_ += deltaTime;
|
||||
if (finished_timer_ >= finished_delay_ms_) {
|
||||
finished_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,21 +26,22 @@ class SmartSprite : public AnimatedSprite {
|
||||
auto hasFinished() const -> bool { return finished_; } // Indica si ya ha terminado
|
||||
|
||||
// --- Setters ---
|
||||
void setFinishedCounter(int value) { finished_counter_ = value; } // Establece el contador para deshabilitarlo
|
||||
void setDestX(int x) { dest_x_ = x; } // Establece la posición de destino en X
|
||||
void setDestY(int y) { dest_y_ = y; } // Establece la posición de destino en Y
|
||||
void setEnabled(bool value) { enabled_ = value; } // Habilita o deshabilita el objeto
|
||||
void setFinishedDelay(float value) { finished_delay_ms_ = value; } // Establece el retraso para deshabilitarlo (ms)
|
||||
void setDestX(int x) { dest_x_ = x; } // Establece la posición de destino en X
|
||||
void setDestY(int y) { dest_y_ = y; } // Establece la posición de destino en Y
|
||||
void setEnabled(bool value) { enabled_ = value; } // Habilita o deshabilita el objeto
|
||||
|
||||
private:
|
||||
// --- Variables de estado ---
|
||||
int dest_x_ = 0; // Posición de destino en el eje X
|
||||
int dest_y_ = 0; // Posición de destino en el eje Y
|
||||
int finished_counter_ = 0; // Contador para deshabilitarlo
|
||||
int dest_x_ = 0; // Posición de destino en el eje X
|
||||
int dest_y_ = 0; // Posición de destino en el eje Y
|
||||
float finished_delay_ms_ = 0.0f; // Retraso para deshabilitarlo (ms)
|
||||
float finished_timer_ = 0.0f; // Timer acumulado (ms)
|
||||
bool on_destination_ = false; // Indica si está en el destino
|
||||
bool finished_ = false; // Indica si ya ha terminado
|
||||
bool enabled_ = false; // Indica si el objeto está habilitado
|
||||
|
||||
// --- Métodos internos ---
|
||||
void checkFinished(); // Comprueba si ha terminado
|
||||
void checkMove(); // Comprueba el movimiento
|
||||
void checkFinished(float deltaTime); // Comprueba si ha terminado (time-based)
|
||||
void checkMove(); // Comprueba el movimiento
|
||||
};
|
||||
@@ -40,12 +40,10 @@ void Tabe::render() {
|
||||
|
||||
// Mueve el objeto (time-based)
|
||||
void Tabe::move(float deltaTime) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
|
||||
const int X = static_cast<int>(x_);
|
||||
speed_ += accel_ * frameFactor;
|
||||
x_ += speed_ * frameFactor;
|
||||
speed_ += accel_ * deltaTime;
|
||||
x_ += speed_ * deltaTime;
|
||||
fly_distance_ -= std::abs(X - static_cast<int>(x_));
|
||||
|
||||
// Comprueba si sale por los bordes
|
||||
@@ -80,7 +78,7 @@ void Tabe::move(float deltaTime) {
|
||||
if (fly_distance_ <= 0) {
|
||||
if (waiting_counter_ > 0) {
|
||||
accel_ = speed_ = 0.0F;
|
||||
waiting_counter_ -= frameFactor;
|
||||
waiting_counter_ -= deltaTime;
|
||||
if (waiting_counter_ < 0) waiting_counter_ = 0;
|
||||
} else {
|
||||
constexpr int CHOICES = 4;
|
||||
@@ -132,22 +130,22 @@ void Tabe::enable() {
|
||||
void Tabe::setRandomFlyPath(Direction direction, int length) {
|
||||
direction_ = direction;
|
||||
fly_distance_ = length;
|
||||
waiting_counter_ = 5 + rand() % 15;
|
||||
waiting_counter_ = 0.083f + (rand() % 15) * 0.0167f; // 5-20 frames converted to seconds (5/60 to 20/60)
|
||||
Audio::get()->playSound("tabe.wav");
|
||||
|
||||
constexpr float SPEED = 2.0F;
|
||||
constexpr float SPEED = 120.0f; // 2 pixels/frame * 60fps = 120 pixels/second
|
||||
|
||||
switch (direction) {
|
||||
case Direction::TO_THE_LEFT: {
|
||||
speed_ = -1.0F * SPEED;
|
||||
accel_ = -1.0F * (1 + rand() % 10) / 30.0F;
|
||||
accel_ = -1.0F * (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds
|
||||
sprite_->setFlip(SDL_FLIP_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
case Direction::TO_THE_RIGHT: {
|
||||
speed_ = SPEED;
|
||||
accel_ = (1 + rand() % 10) / 30.0F;
|
||||
accel_ = (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds
|
||||
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
||||
break;
|
||||
}
|
||||
@@ -169,7 +167,7 @@ void Tabe::setState(State state) {
|
||||
|
||||
case State::HIT:
|
||||
sprite_->setCurrentAnimation("hit");
|
||||
hit_counter_ = 5;
|
||||
hit_counter_ = 0.083f; // 5 frames converted to seconds (5/60)
|
||||
++number_of_hits_;
|
||||
break;
|
||||
|
||||
@@ -182,9 +180,7 @@ void Tabe::setState(State state) {
|
||||
// Actualiza el estado (time-based)
|
||||
void Tabe::updateState(float deltaTime) {
|
||||
if (state_ == State::HIT) {
|
||||
// Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
hit_counter_ -= frameFactor;
|
||||
hit_counter_ -= deltaTime;
|
||||
if (hit_counter_ <= 0) {
|
||||
setState(State::FLY);
|
||||
}
|
||||
|
||||
@@ -81,32 +81,6 @@ void TiledBG::render() {
|
||||
SDL_RenderTexture(renderer_, canvas_, &window_, &pos_);
|
||||
}
|
||||
|
||||
// Actualiza la lógica de la clase (frame-based)
|
||||
void TiledBG::update() {
|
||||
updateDesp();
|
||||
updateStop();
|
||||
|
||||
switch (mode_) {
|
||||
case TiledBGMode::DIAGONAL: {
|
||||
// El tileado de fondo se desplaza en diagonal
|
||||
window_.x = static_cast<int>(desp_) % TILE_WIDTH;
|
||||
window_.y = static_cast<int>(desp_) % TILE_HEIGHT;
|
||||
|
||||
break;
|
||||
}
|
||||
case TiledBGMode::CIRCLE: {
|
||||
// El tileado de fondo se desplaza en circulo
|
||||
const int INDEX = static_cast<int>(desp_) % 360;
|
||||
|
||||
window_.x = 128 + (static_cast<int>(sin_[(INDEX + 270) % 360] * 128));
|
||||
window_.y = 128 + (static_cast<int>(sin_[(360 - INDEX) % 360] * 96));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la lógica de la clase (time-based)
|
||||
void TiledBG::update(float delta_time) {
|
||||
updateDesp(delta_time);
|
||||
@@ -133,40 +107,20 @@ void TiledBG::update(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Detiene el desplazamiento de forma ordenada (frame-based)
|
||||
void TiledBG::updateStop() {
|
||||
if (stopping_) {
|
||||
const int UMBRAL = 20 * speed_; // Ajusta este valor según la precisión deseada
|
||||
|
||||
// Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0)
|
||||
if (window_.x >= TILE_WIDTH - UMBRAL) {
|
||||
speed_ /= 1.05F; // Reduce gradualmente la velocidad
|
||||
|
||||
// Asegura que no baje demasiado
|
||||
speed_ = std::max(speed_, 0.1F);
|
||||
}
|
||||
|
||||
// Si estamos en 0, detener
|
||||
if (window_.x == 0) {
|
||||
speed_ = 0.0F;
|
||||
stopping_ = false; // Desactivamos el estado de "stopping"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detiene el desplazamiento de forma ordenada (time-based)
|
||||
void TiledBG::updateStop(float delta_time) {
|
||||
if (stopping_) {
|
||||
const int UMBRAL = 20 * speed_; // Ajusta este valor según la precisión deseada
|
||||
const int UMBRAL = STOP_THRESHOLD_FACTOR * speed_;
|
||||
|
||||
// Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0)
|
||||
if (window_.x >= TILE_WIDTH - UMBRAL) {
|
||||
// Convertir 1.05F por frame a por milisegundo: (1.05^(60*delta_time/1000))
|
||||
float deceleration_factor = std::pow(1.05F, 60.0F * delta_time / 1000.0F);
|
||||
speed_ /= deceleration_factor;
|
||||
// Aplicar desaceleración time-based
|
||||
float frame_rate = 60.0F;
|
||||
float deceleration_per_ms = std::pow(DECELERATION_FACTOR, frame_rate * delta_time / 1000.0F);
|
||||
speed_ /= deceleration_per_ms;
|
||||
|
||||
// Asegura que no baje demasiado
|
||||
speed_ = std::max(speed_, 0.1F);
|
||||
speed_ = std::max(speed_, MIN_SPEED);
|
||||
}
|
||||
|
||||
// Si estamos en 0, detener
|
||||
|
||||
@@ -24,9 +24,8 @@ class TiledBG {
|
||||
~TiledBG();
|
||||
|
||||
// --- Métodos principales ---
|
||||
void render(); // Pinta la clase en pantalla
|
||||
void update(); // Actualiza la lógica de la clase (compatibilidad)
|
||||
void update(float delta_time); // Actualiza la lógica de la clase
|
||||
void render(); // Pinta la clase en pantalla
|
||||
void update(float delta_time); // Actualiza la lógica de la clase
|
||||
|
||||
// --- Configuración ---
|
||||
void setSpeed(float speed) { speed_ = speed; } // Establece la velocidad
|
||||
@@ -38,8 +37,11 @@ class TiledBG {
|
||||
|
||||
private:
|
||||
// --- Constantes ---
|
||||
static constexpr int TILE_WIDTH = 64; // Ancho del tile
|
||||
static constexpr int TILE_HEIGHT = 64; // Alto del tile
|
||||
static constexpr int TILE_WIDTH = 64; // Ancho del tile
|
||||
static constexpr int TILE_HEIGHT = 64; // Alto del tile
|
||||
static constexpr float STOP_THRESHOLD_FACTOR = 20.0f; // Factor para umbral de parada
|
||||
static constexpr float DECELERATION_FACTOR = 1.05f; // Factor de desaceleración
|
||||
static constexpr float MIN_SPEED = 0.1f; // Velocidad mínima
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
@@ -55,9 +57,7 @@ class TiledBG {
|
||||
bool stopping_ = false; // Indica si se está deteniendo
|
||||
|
||||
// --- Métodos internos ---
|
||||
void fillTexture(); // Rellena la textura con el contenido
|
||||
void updateDesp() { desp_ += speed_; } // Actualiza el desplazamiento (frame-based)
|
||||
void updateDesp(float delta_time) { desp_ += speed_ * delta_time / (1000.0f / 60.0f); } // Actualiza el desplazamiento (time-based)
|
||||
void updateStop(); // Detiene el desplazamiento de forma ordenada (frame-based)
|
||||
void updateStop(float delta_time); // Detiene el desplazamiento de forma ordenada (time-based)
|
||||
void fillTexture(); // Rellena la textura con el contenido
|
||||
void updateDesp(float delta_time) { desp_ += speed_ * delta_time; } // Actualiza el desplazamiento (time-based)
|
||||
void updateStop(float delta_time); // Detiene el desplazamiento de forma ordenada (time-based)
|
||||
};
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
#include "text.h" // Para Text
|
||||
|
||||
// Actualiza el objeto
|
||||
// Actualiza el objeto (delta_time en ms)
|
||||
void Writer::update(float delta_time) {
|
||||
if (enabled_) {
|
||||
if (!completed_) {
|
||||
// No completado
|
||||
writing_timer_ += delta_time;
|
||||
if (writing_timer_ >= speed_ms_) {
|
||||
if (writing_timer_ >= speed_interval_) {
|
||||
index_++;
|
||||
writing_timer_ = 0.0f;
|
||||
}
|
||||
@@ -24,6 +24,12 @@ void Writer::update(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el objeto (delta_time en segundos)
|
||||
void Writer::updateS(float delta_time) {
|
||||
// Convierte segundos a milisegundos y usa la lógica normal
|
||||
update(delta_time * 1000.0f);
|
||||
}
|
||||
|
||||
// Dibuja el objeto en pantalla
|
||||
void Writer::render() const {
|
||||
if (enabled_) {
|
||||
@@ -52,11 +58,18 @@ void Writer::setCaption(const std::string &text) {
|
||||
length_ = text.length();
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
// Establece el valor de la variable (frames)
|
||||
void Writer::setSpeed(int value) {
|
||||
// Convierte frames a milisegundos (frames * 16.67ms)
|
||||
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||
speed_ms_ = static_cast<float>(value) * FRAME_TIME_MS;
|
||||
constexpr float FRAME_TIME_MS = 16.67f;
|
||||
speed_interval_ = static_cast<float>(value) * FRAME_TIME_MS;
|
||||
writing_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
// Establece la velocidad en segundos entre caracteres
|
||||
void Writer::setSpeedS(float value) {
|
||||
// Convierte segundos a milisegundos para consistencia interna
|
||||
speed_interval_ = value * 1000.0f;
|
||||
writing_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
@@ -76,6 +89,12 @@ void Writer::setFinishedTimerMs(float time_ms) {
|
||||
enabled_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
// Establece el temporizador para deshabilitar el objeto (en segundos)
|
||||
void Writer::setFinishedTimerS(float time_s) {
|
||||
enabled_timer_target_ = time_s * 1000.0f; // Convertir segundos a milisegundos
|
||||
enabled_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
// Centra la cadena de texto a un punto X
|
||||
void Writer::center(int x) {
|
||||
setPosX(x - (text_->length(caption_, kerning_) / 2));
|
||||
|
||||
@@ -15,17 +15,20 @@ class Writer {
|
||||
~Writer() = default;
|
||||
|
||||
// --- Métodos principales ---
|
||||
void update(float delta_time); // Actualiza el objeto
|
||||
void render() const; // Dibuja el objeto en pantalla
|
||||
void update(float delta_time); // Actualiza el objeto (delta_time en ms)
|
||||
void updateS(float delta_time); // Actualiza el objeto (delta_time en segundos)
|
||||
void render() const; // Dibuja el objeto en pantalla
|
||||
|
||||
// --- Setters ---
|
||||
void setPosX(int value); // Establece la posición X
|
||||
void setPosY(int value); // Establece la posición Y
|
||||
void setKerning(int value); // Establece el kerning (espaciado entre caracteres)
|
||||
void setCaption(const std::string &text); // Establece el texto a escribir
|
||||
void setSpeed(int value); // Establece la velocidad de escritura
|
||||
void setSpeed(int value); // Establece la velocidad de escritura (frames)
|
||||
void setSpeedS(float value); // Establece la velocidad de escritura (segundos entre caracteres)
|
||||
void setEnabled(bool value); // Habilita o deshabilita el objeto
|
||||
void setFinishedTimerMs(float time_ms); // Establece el temporizador para deshabilitar el objeto (en ms)
|
||||
void setFinishedTimerS(float time_s); // Establece el temporizador para deshabilitar el objeto (en segundos)
|
||||
|
||||
void center(int x); // Centra la cadena de texto a un punto X
|
||||
|
||||
@@ -42,7 +45,7 @@ class Writer {
|
||||
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
|
||||
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
|
||||
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
|
||||
float speed_ms_ = 0.0f; // Velocidad de escritura en milisegundos
|
||||
float speed_interval_ = 0.0f; // Intervalo entre caracteres (ms para compatibilidad)
|
||||
float writing_timer_ = 0.0f; // Temporizador de escritura para cada caracter
|
||||
int index_ = 0; // Posición del texto que se está escribiendo
|
||||
int length_ = 0; // Longitud de la cadena a escribir
|
||||
|
||||
Reference in New Issue
Block a user