feat: estat DISABLED i spawn aeri al començar la sala — v0.25.0

This commit is contained in:
JailDesigner committed 2026-04-26 14:17:17 +02:00
1 parent 645db217fa
commit 580c13e854
8 files changed
+280 -104

No files matched your search

+41 -1
View File
@@ -50,6 +50,14 @@ class Player : public AnimatedSprite {
// posteriors a `exit()` són no-op. El reset el porta `respawn()`
// (cridada per GameScene en transició OUTRO → INTRO).
EXITED,
// Slot de jugador inactiu: instanciat però fora de partida. Mateix
// perfil físic que EXITED (invisible, sense input, sense col·lisió,
// ignorat pel resolver PvP), però amb semàntica diferent: no
// compta com a "ha completat la sala" ni dispara `level_complete`.
// Usat per (a) el slot del segon jugador en single-player, (b)
// tots els slots durant les transicions de sala abans del spawn
// aeri, i (c) en el futur, l'estat post-mort abans del respawn.
DISABLED,
};
// Geometria carregada des del YAML del player (p.ex. `data/player/sam.yaml`).
@@ -184,6 +192,15 @@ class Player : public AnimatedSprite {
[[nodiscard]] auto isAirborne() const -> bool { return state_ == State::AIRBORNE; }
[[nodiscard]] auto isHurt() const -> bool { return state_ == State::HURT; }
[[nodiscard]] auto isExited() const -> bool { return state_ == State::EXITED; }
[[nodiscard]] auto isDisabled() const -> bool { return state_ == State::DISABLED; }
// Resum dels estats "fora del món": EXITED i DISABLED comparteixen el
// mateix perfil físic (no es pinten, no llegeixen input, no
// col·lisionen, no participen al resolver PvP). Tots dos gates de
// l'update i el render comproven aquesta combinació amb una sola
// crida per evitar oblits si demà afegim un tercer estat-fora-del-món.
[[nodiscard]] auto isOutOfPlay() const -> bool {
return state_ == State::EXITED || state_ == State::DISABLED;
}
// Tangible per a contactes jugador↔jugador: només els estats a terra
// amb cos sòlid. AIRBORNE i HURT són intangibles (es travessen).
// EXITED tampoc — el jugador ha eixit lògicament i ja no és al món.
@@ -216,9 +233,32 @@ class Player : public AnimatedSprite {
// Reset complet a l'estat inicial: posició a (x, y), velocitats a 0,
// estat GROUNDED, qualsevol flag de control reinicialitzat. Cridat
// per GameScene a la transició ROOM_OUTRO → ROOM_INTRO. Idempotent
// (es pot cridar des de qualsevol estat).
// (es pot cridar des de qualsevol estat). Es manté disponible per a
// qualsevol cas futur on calgui aparèixer el jugador ja a terra
// sense la cinemàtica de caiguda; el flux estàndard d'arrencada de
// sala usa `disable()` + `spawnFromAir()`.
void respawn(float x, float y);
// Posa el jugador en el slot inactiu (DISABLED). Idempotent: la
// segona crida és no-op. Mateix patró que `exit()` per simetria.
// No publica res al bus — el GameScene decideix quan disparar el
// `spawnFromAir` posterior, i la transició DISABLED↔jugant és
// ortogonal a `level_complete`. Útil per:
// - el slot del segon jugador en single-player,
// - el període entre setState(ROOM_INTRO) i el trigger del spawn,
// - el futur estat post-mort (abans del respawn temporitzat).
void disable();
// Cinemàtica d'aparició: posiciona el jugador al seu tile final
// (x, y al sistema de coordenades del sprite) i el deixa en
// AIRBORNE a una altura derivada de la geometria del playfield —
// prou per arrencar fora del marc i caure recte fins al sòl. La
// velocitat horitzontal queda a zero (caiguda perfectament
// vertical). En tocar terra, el flux normal d'AIRBORNE→
// LANDING_STUN→GROUNDED el reactiva amb input. Reutilitzable per
// al respawn post-mort: mateixa entrada cinemàtica.
void spawnFromAir(float x, float y);
// Alçada actual del salt (píxels visuals per damunt del sòl).
// 0 quan està a terra. L'usa el render i el sistema de col·lisions
// per altura.