Files
aee-arcade/docs/player-animations.md
T

3.5 KiB

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 (14/14) verdes.
  • 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.