- Registre de commits omplert amb els hashes reals dels 3 commits de la rama (a3b03b8/64e0178/d9f6fb4). - player-animations.md: el recompte de smoke tests deia "14/14" però `tests/test_entities_smoke.cpp` només invoca 13 funcions `test*` des de `main()`. Nota corregida a "13/13" amb explicació. Tanca els 4 ítems DEFERRED de `audit/game` (COUP-02, COUP-03, CONV-02 part Options, PATCH-01). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
3.7 KiB
Markdown
81 lines
3.7 KiB
Markdown
# Animacions i direccionalitat del jugador
|
|
|
|
Documenta els afegits d'aquesta sessió a `source/game/entities/player.*`: sis
|
|
animacions direccionals amb `facing_` persistent, regla de flip només per al
|
|
lateral i transició automàtica a `stand` quan la col·lisió bloqueja el
|
|
moviment. Tot el canvi és local al `Player`; no s'ha tocat l'EntityManager
|
|
ni el bus.
|
|
|
|
## 1. YAML — sis animacions
|
|
|
|
El fitxer `data/player/player.yaml` defineix ara sis animacions, agrupades
|
|
en tres files de 4 frames sobre `player.gif` (convenció habitual: d'esquerra
|
|
a dreta i de dalt a baix):
|
|
|
|
| Nom | Frames | Descripció |
|
|
|---------------|------------|----------------------------|
|
|
| `stand_down` | `[0]` | parat mirant cap avall |
|
|
| `walk_down` | `[0..3]` | caminant cap avall |
|
|
| `stand_up` | `[4]` | parat mirant cap amunt |
|
|
| `walk_up` | `[4..7]` | caminant cap amunt |
|
|
| `stand` | `[8]` | parat lateral |
|
|
| `walk` | `[8..11]` | caminant lateral |
|
|
|
|
Les laterals (`stand` i `walk`) ja existien; les variants `_up` i `_down`
|
|
són noves i permeten distingir visualment la direcció de moviment.
|
|
|
|
## 2. `Facing` persistent
|
|
|
|
S'ha afegit l'enum privat `Facing { SIDE, UP, DOWN }` amb el membre
|
|
`facing_{SIDE}`. La tria es fa a cada `update`, amb prevalença lateral
|
|
per si un dia es permetessin diagonals:
|
|
|
|
- `vx != 0` → `SIDE` (inclou diagonals).
|
|
- `vx == 0 && vy < 0` → `UP`.
|
|
- `vx == 0 && vy > 0` → `DOWN`.
|
|
- Cap input → es conserva l'últim `facing_` perquè l'animació `stand_*`
|
|
coincideixi amb l'última direcció caminada.
|
|
|
|
## 3. Regla de flip
|
|
|
|
- `SIDE`: el sprite es flipeja horitzontalment si `vx < 0`, i es restaura
|
|
a `FLIP_NONE` si `vx > 0`. El sprite original mira a la dreta.
|
|
- `UP` / `DOWN`: el flip es força explícitament a `FLIP_NONE`. Els sprites
|
|
frontals/dorsals no s'han d'espillar només perquè l'últim lateral havia
|
|
estat cap a l'esquerra.
|
|
|
|
## 4. `stand` automàtic a la col·lisió
|
|
|
|
Quan el jugador prem una tecla però la col·lisió (mapa o sarcòfag) li
|
|
impedeix avançar, l'animació `walk*` s'atura i es força la variant
|
|
`stand_*` corresponent al facing. L'algorisme:
|
|
|
|
1. Al principi del frame es captura `FRAME_START_X` / `FRAME_START_Y`.
|
|
2. S'aplica snap al passadís perpendicular si hi ha pur moviment H o V.
|
|
3. `AnimatedSprite::update` integra la velocitat; la col·lisió
|
|
eix-separada reverteix cada eix si `Map::collides(baseBox())`.
|
|
4. Després de `clampToPlayfield`, es compara la posició final amb el
|
|
valor capturat al pas 1. Si és idèntica, `MOVED = false` i es tria
|
|
`stand` / `stand_up` / `stand_down` segons `facing_`.
|
|
5. Si hi ha hagut moviment real (incloent-hi snap), s'aplica la variant
|
|
`walk*` del mateix facing.
|
|
|
|
D'aquesta manera, xocar contra un mur o un sarcòfag fa que el jugador es
|
|
quede immòbil en compte d'animar el caminat "en el lloc". El facing
|
|
segueix reflectint la intenció (on vol anar), no el resultat, perquè
|
|
l'`stand_up` d'empentar-se contra un mur ha de mostrar el personatge
|
|
mirant amunt.
|
|
|
|
## 5. Estat
|
|
|
|
- DONE: sis animacions al YAML, `facing_` persistent, flip condicionat,
|
|
`stand` automàtic a la col·lisió.
|
|
- Build i smoke tests (13/13) verdes. (Aquesta nota deia "14/14" abans;
|
|
el comptatge real al `tests/test_entities_smoke.cpp` són 13 funcions
|
|
`test*` invocades des de `main()` — corregit a `refactor/options-class`.)
|
|
- Sense smoke test dedicat: la lògica està entrellaçada amb teclat i
|
|
`Map::collides`; l'smoke actual de `Player` no cobreix teclat simulat.
|
|
- Pendent (ajornat): si algun dia es vol feedback auditiu de wall-bump
|
|
(so en xocar), la condició natural és `!MOVED && (vx != 0 || vy != 0)`
|
|
al final d'`update`.
|