feat(player): nou estat HURT — caure damunt d'un altre el llança projectat
This commit is contained in:
1 parent
188f035333
commit
e8407ce35e
5 files changed
+310
-119
No files matched your search
@@ -28,15 +28,22 @@ class Player : public AnimatedSprite {
|
||||
|
||||
// Estat d'alt nivell del jugador. Ortogonal a `Facing`/`Cardinal`
|
||||
// (direcció) i a `being_pushed_` (flag d'animació). Determina què pot
|
||||
// fer el jugador aquest frame: GROUNDED accepta tot l'input habitual
|
||||
// i el botó de salt; AIRBORNE ignora canvis de direcció (la velocitat
|
||||
// i el facing queden fixats al moment del despegue, sols la física
|
||||
// del salt mou jump_z_/jump_vz_); LANDING_STUN bloca tot l'input fins
|
||||
// que el timer s'esgota.
|
||||
// fer el jugador aquest frame:
|
||||
// GROUNDED → input normal, pot saltar.
|
||||
// AIRBORNE → física del salt; ignora input direccional, sense
|
||||
// col·lisió amb caminants però sí amb altres
|
||||
// saltadors a la mateixa franja d'alçada (rebot).
|
||||
// LANDING_STUN → 200ms post-aterratge, sense input ni moviment.
|
||||
// HURT → projectat sense control (cau d'algú al damunt o,
|
||||
// en el futur, fuetada): velocitat inicial alta
|
||||
// que decau per inèrcia fins a parar (~2 tiles).
|
||||
// No col·lisiona amb cap altre jugador. Quan
|
||||
// s'atura, torna a GROUNDED.
|
||||
enum class State : std::uint8_t {
|
||||
GROUNDED,
|
||||
AIRBORNE,
|
||||
LANDING_STUN,
|
||||
HURT,
|
||||
};
|
||||
|
||||
// Geometria carregada des del YAML del player (p.ex. `data/player/sam.yaml`).
|
||||
@@ -169,6 +176,12 @@ class Player : public AnimatedSprite {
|
||||
// GameScene (per saber si renderitzar la sombra).
|
||||
[[nodiscard]] auto getState() const -> State { return state_; }
|
||||
[[nodiscard]] auto isAirborne() const -> bool { return state_ == State::AIRBORNE; }
|
||||
[[nodiscard]] auto isHurt() const -> bool { return state_ == State::HURT; }
|
||||
// Tangible per a contactes jugador↔jugador: només els estats a terra
|
||||
// amb cos sòlid. AIRBORNE i HURT són intangibles (es travessen).
|
||||
[[nodiscard]] auto isPvpTangible() const -> bool {
|
||||
return state_ == State::GROUNDED || state_ == State::LANDING_STUN;
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -385,6 +398,27 @@ class Player : public AnimatedSprite {
|
||||
// manca, deixa la mecànica del salt desactivada.
|
||||
static void readJumpBlock(const fkyaml::node& yaml);
|
||||
|
||||
// Configuració de l'estat HURT (estat post-impacte). Si
|
||||
// `initial_speed_px_per_s == 0` el jugador entra i surt
|
||||
// instantàniament (cap moviment).
|
||||
struct HurtConfig {
|
||||
float initial_speed_px_per_s{0.0F}; // Velocitat amb què surt projectat (px/s).
|
||||
int brake_time_ms{0}; // Temps en que la velocitat decau a 0.
|
||||
};
|
||||
static HurtConfig hurt_config;
|
||||
|
||||
// Llig el bloc `hurt:` del YAML i n'omple `hurt_config`.
|
||||
static void readHurtBlock(const fkyaml::node& yaml);
|
||||
|
||||
// Activa l'estat HURT: el jugador queda projectat amb velocitat
|
||||
// inicial `hurt_config.initial_speed_px_per_s` cap a la direcció que
|
||||
// doni més recorregut lliure (provem els 4 cardinals i triem el de
|
||||
// major distància fins a topar amb un mur). Decelera linealment fins
|
||||
// a parar i, en eixe instant, torna a GROUNDED. Sense col·lisió amb
|
||||
// altres jugadors mentre dura — ja que es travessa l'eventual
|
||||
// solapament inicial.
|
||||
void enterHurt();
|
||||
|
||||
// Estat de la màquina d'estats. Mutat per `tick`/`applyMovement`. Per
|
||||
// defecte GROUNDED al spawn.
|
||||
State state_{State::GROUNDED};
|
||||
@@ -418,17 +452,23 @@ class Player : public AnimatedSprite {
|
||||
// `applyMovement` puga disparar la resolució del solapament PvP).
|
||||
auto integrateJump(float delta_time) -> bool;
|
||||
|
||||
// En aterrar, si la hit-box del jugador solapa amb la d'un altre,
|
||||
// separa els dos sense ficar-los dins d'un mur. Algoritme:
|
||||
// 1. Calcula la direcció centre→centre i la magnitud de
|
||||
// solapament (MTV axis-aligned).
|
||||
// 2. Empenta l'altre cap a fora; si no cap (mur al darrere),
|
||||
// reverteix i empenta el saltador cap al sentit oposat.
|
||||
// 3. Si tampoc cap, es deixa l'estat com està (overlap residual);
|
||||
// a la pràctica aquest cas és molt rar i el usuari ja ha
|
||||
// acceptat que no és crític.
|
||||
// En aterrar, si la base-box del jugador solapa amb la d'un altre,
|
||||
// l'altre entra en `HURT` i surt projectat per `enterHurt`. El
|
||||
// saltador (this) es queda al lloc — el moviment per separar-los
|
||||
// el fa el HURT en cours, no una empenta forçada.
|
||||
void resolveLandingOverlap();
|
||||
|
||||
// Branques de `applyMovement` extretes per acotar la complexitat
|
||||
// cognitiva. Cada estat especial gestiona el seu propi cicle
|
||||
// (animació, tryMove o no, publicació de tile).
|
||||
void applyHurtMovement(float delta_time);
|
||||
void applyLandingStunMovement(float delta_time);
|
||||
|
||||
// Publica `on_tile_entered` al bus si el tile ha canviat respecte a
|
||||
// l'últim publicat. Comú a totes les branques de `applyMovement` que
|
||||
// pinten el sòl (GROUNDED, HURT, LANDING_STUN; en AIRBORNE no).
|
||||
void publishTileEnteredIfChanged();
|
||||
|
||||
// Estat del gir en curs. Mentre `turning_remaining_ms_ > 0`, el facing/
|
||||
// flip es manté forçat a `intermediate_cardinal_` i l'animació es força
|
||||
// a `stand` encara que el moviment continuï. En esgotar-se el timer,
|
||||
|
||||
Reference in new issue
Block a user