Fase 6e: migrar Bullet al sistema de fisica vectorial
Las balas pasan a ser cinematicas dentro del PhysicsWorld: - body_.setMass(0.5), radius=0 (no colisionan fisicamente) - disparar() setea body_.position + body_.velocity cartesiana (140 px/s) - update() detecta salida del PLAYAREA via body_.position y desactiva - postUpdate() sincroniza center_ desde body_.position - desactivar() detiene el body para evitar deriva mientras inactiva GameScene registra los bodies en init() y llama postUpdate(). El gameplay sigue gestionando colisiones bullet-enemy/bullet-ship con check_collision (el radio gameplay es BULLET_RADIUS=3, expuesto via getCollisionRadius). Renames a camelBack (clang-tidy): get_owner_id->getOwnerId, get_grace_timer->getGraceTimer. MIGRATION_PLAN.md actualizado: Fase 6e cerrada, Fase 7 (SDL3 GPU) siguiente. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+33
-34
@@ -35,44 +35,37 @@ Tag de seguridad: **`beta-3.0`** (snapshot de `main` antes de empezar).
|
||||
| 5 — Infraestructura física (`RigidBody`, `PhysicsWorld`) | ✅ | `0fd9360` |
|
||||
| 6a+b — `body_` en Entity + `world_` en GameScene | ✅ | `0574077` |
|
||||
| 6c — Migrar Ship | ✅ | `2fe22ff` |
|
||||
| **6d — Migrar Enemy** | ✅ | `27242f5` |
|
||||
| 6e — Migrar Bullet | 🔲 **siguiente** | — |
|
||||
| 7 — Migración a SDL3 GPU (sin fallback) | 🔲 | — |
|
||||
| 6d — Migrar Enemy | ✅ | `27242f5` |
|
||||
| **6e — Migrar Bullet** | ✅ | (este commit) |
|
||||
| 7 — Migración a SDL3 GPU (sin fallback) | 🔲 **siguiente** | — |
|
||||
| 8 — Postprocesado, color, paleta por tipo | 🔲 | — |
|
||||
| 9 — Refactor de GameScene (2.877 LOC → módulos) | 🔲 | — |
|
||||
| 10 — Tuning final de masa/restitución/damping | 🔲 | — |
|
||||
|
||||
## Lo que queda inmediato (Fase 6e)
|
||||
## Lo que queda inmediato (Fase 7)
|
||||
|
||||
Migrar `Bullet` al PhysicsWorld. Es la entidad más simple:
|
||||
**Migración del renderizado a SDL3 GPU sin fallback.**
|
||||
|
||||
- Constructor: `body_.setMass(0.5)`, `radius = BULLET_RADIUS = 3`, `restitution = 0`
|
||||
(NO rebotan, salen del PLAYAREA y se desactivan), `linear_damping = 0`.
|
||||
- `init()` resetea body_.
|
||||
- `disparar()`/spawn: setear `body_.position` y `body_.velocity` cartesiano a `140 px/s` en
|
||||
dirección del shooter.
|
||||
- `update()`: detectar si salió del PLAYAREA con margen; si sí, `desactivar()`.
|
||||
- `postUpdate()`: sincronizar `center_` desde `body_.position`.
|
||||
- En GameScene: registrar bodies en `init()`, llamar `postUpdate()` en `update()`.
|
||||
- Cuando un bullet se desactiva: `body_.radius = 0` para no estorbar.
|
||||
- **Edge case importante**: las balas NO deben rebotar contra las naves de los
|
||||
jugadores. Las colisiones físicas las hace el world automáticamente. Para
|
||||
evitarlo:
|
||||
- Opción A: dejar que el world resuelva el impulso, pero la lógica de
|
||||
gameplay (en GameScene) detecta el hit y desactiva el bullet antes de que
|
||||
se vea visualmente el rebote (1 frame de margen).
|
||||
- Opción B: hacer que `body_.radius = 0` para las balas, así no colisionan
|
||||
físicamente, y solo las colisiones de gameplay (check_collision en
|
||||
GameScene) las gestionan.
|
||||
- Recomendado: **Opción B**. Las balas físicamente no necesitan colisión
|
||||
del world — son cinemáticas. Solo el gameplay las usa.
|
||||
Fase 6e completada: las balas son cinemáticas dentro del PhysicsWorld (radius=0
|
||||
en el world → no colisionan físicamente, solo gameplay-level via check_collision).
|
||||
Body con mass=0.5, restitution=0, damping=0. `disparar()` setea
|
||||
`body_.position` + `body_.velocity` cartesiana; `update()` detecta salida de
|
||||
PLAYAREA y desactiva; `postUpdate()` sincroniza `center_` desde body. Smoke
|
||||
test xvfb pasa sin errores.
|
||||
|
||||
Tras 6e, hacer **Fase 10 (tuning)**: ajustar masas, restitución, damping según
|
||||
feel. Probablemente:
|
||||
- Ship: subir `mass` a 15-20 (más "anclado", menos empujable por enemies).
|
||||
- Enemies: reducir `restitution` a 0.85 (rebote más natural, sin "pelota").
|
||||
- Probar collision con friendly fire / nave-enemy en debris ahora que ambos
|
||||
tienen body real.
|
||||
Decisión técnica del proyecto: **no fallback a SDL_Renderer**
|
||||
([memoria](./.claude/projects/-home-sergio-gitea-orni-attack/memory/project_no_sdl_fallback.md)).
|
||||
La fase 7 reemplaza completamente el pipeline actual de SDL_Renderer
|
||||
(`SDL_RenderLine`, `SDL_RenderGeometry`) por SDL3 GPU.
|
||||
|
||||
Tareas previstas Fase 7:
|
||||
- Sustituir `SDL_Renderer*` por `SDL_GPUDevice*` en SDLManager.
|
||||
- Setup de swapchain + shaders básicos (vertex + fragment) para líneas vectoriales.
|
||||
- Migrar `Rendering::render_shape` a un pipeline GPU que reciba vertex buffers.
|
||||
- Postprocesado mínimo (Fase 8): bloom/glow, paleta por tipo de entidad.
|
||||
|
||||
**Fase 10 (tuning)** queda pendiente para después de SDL3 GPU + postpro. El usuario
|
||||
prefiere terminar la migración técnica antes de tunear feel.
|
||||
|
||||
## Memoria del proyecto
|
||||
|
||||
@@ -115,16 +108,22 @@ Resumen:
|
||||
indica en qué fase estamos).
|
||||
6. Tras cada commit, push automático: `git push origin rewrite/physics-gpu`.
|
||||
|
||||
## Configuración física actual (Fase 6d)
|
||||
## Configuración física actual (Fase 6e)
|
||||
|
||||
| Entidad | mass | radius | restitution | linear_damping | angular_damping |
|
||||
| Entidad | mass | radius (world) | restitution | linear_damping | angular_damping |
|
||||
|---|---|---|---|---|---|
|
||||
| Ship | 10.0 | 12 | 0.6 | 1.5 | 0.0 |
|
||||
| Enemy Pentagon | 5.0 | 20 | 1.0 | 0.0 | 0.0 |
|
||||
| Enemy Quadrat | 8.0 | 20 | 1.0 | 0.0 | 0.0 |
|
||||
| Enemy Molinillo | 4.0 | 20 | 1.0 | 0.0 | 0.0 |
|
||||
| Bullet | (pendiente Fase 6e) | 3 | 0 | 0 | 0 |
|
||||
| Bullet | 0.5 | **0** (cinemática) | 0 | 0 | 0 |
|
||||
| Wall (PLAYAREA bounds) | ∞ (estático) | — | — | — | — |
|
||||
|
||||
Nota: Bullet usa `radius=0` en el body físico para que no participe en las
|
||||
colisiones del world (ni body-body ni bounds). El radio de gameplay
|
||||
(`Defaults::Entities::BULLET_RADIUS = 3`) lo expone vía `getCollisionRadius()`
|
||||
y lo consumen `check_collision` y la detección de salida del PLAYAREA en
|
||||
`Bullet::update`.
|
||||
|
||||
Las paredes son implícitas: `physics_world_.setBounds(PLAYAREA)` en
|
||||
`GameScene::init`. No son `RigidBody` separados, sino un AABB que rebota.
|
||||
|
||||
Reference in New Issue
Block a user