feat(hazard): nou hazard Hole — caiguda per forat amb clip rect
This commit is contained in:
1 parent
d4593d0686
commit
4da50571eb
17 files changed
+376
-15
No files matched your search
@@ -40,6 +40,16 @@ class Player : public AnimatedSprite {
|
||||
// que decau per inèrcia fins a parar (~2 tiles).
|
||||
// No col·lisiona amb cap altre jugador. Quan
|
||||
// s'atura, torna a GROUNDED.
|
||||
// Causa de la mort actual. La passa el caller a `enterDying(cause)` per
|
||||
// triar la presentació visual (`death_<key>` al YAML del player). El
|
||||
// default `GENERIC` cobreix tots els callsites antics (mòmies, etc.)
|
||||
// sense haver de tocar-los; els nous (caiguda per `Hole`, en el futur
|
||||
// pinchos / timeout / etc.) passen la seua causa explícita.
|
||||
enum class DeathCause : std::uint8_t {
|
||||
GENERIC, // mort estàndard — animació `death_spinning`
|
||||
HOLE, // caiguda per agujero — animació `death_hole`
|
||||
};
|
||||
|
||||
enum class State : std::uint8_t {
|
||||
GROUNDED,
|
||||
AIRBORNE,
|
||||
@@ -226,6 +236,21 @@ class Player : public AnimatedSprite {
|
||||
return state_ == State::GROUNDED || state_ == State::LANDING_STUN;
|
||||
}
|
||||
|
||||
// El jugador està caient per un agujero (`Hole`): subestat dins
|
||||
// d'AIRBORNE amb gravetat aplicada SENSE clamp a 0 — `jump_z_` baixa
|
||||
// a negatius fins a `HOLE_FALL_DEPTH`, llavors `enterDying()`. Mentre
|
||||
// dura, `checkPlayerCollisions` salta aquest jugador (cap més hazard
|
||||
// l'ha de tocar). Es neteja a `enterDying()` i a `respawn()`.
|
||||
[[nodiscard]] auto isFallingThroughHole() const -> bool { return falling_through_hole_; }
|
||||
|
||||
// Activa la caída per agujero: snap del jugador al centre (cx, cy) en
|
||||
// coordenades absolutes del canvas, transició a AIRBORNE amb
|
||||
// `jump_z_=0` i `falling_through_hole_=true`, i arma el clip rect
|
||||
// visual a partir de `floor_y` (Y de la base del tile del forat,
|
||||
// canvas píxels). Desactiva input direccional reusant la branca
|
||||
// AIRBORNE existent. No-op si el jugador no està a GROUNDED.
|
||||
void enterHoleFall(float center_x, float center_y, float floor_y);
|
||||
|
||||
// Despawn lògic: el jugador acaba de creuar la porta de sortida.
|
||||
// Idempotent — només la primera crida fa la transició; les
|
||||
// posteriors són no-op. La publicació del `player_exited` al bus
|
||||
@@ -254,7 +279,7 @@ class Player : public AnimatedSprite {
|
||||
// momia mentre la roda no la reinicia). Quan l'animació acaba i
|
||||
// `respawn_delay_ms` expira, `respawn(spawn_x_, spawn_y_)` torna a
|
||||
// GROUNDED i `lives_remaining_` decreix en 1 (pot anar a negatius).
|
||||
void enterDying();
|
||||
void enterDying(DeathCause cause = DeathCause::GENERIC);
|
||||
|
||||
// Coordenades del spawn de respawn (cantó superior-esquerra del
|
||||
// sprite, mateixa convenció que `respawn(x, y)`). El GameScene les
|
||||
@@ -655,6 +680,31 @@ class Player : public AnimatedSprite {
|
||||
float jump_z_{0.0F};
|
||||
float jump_vz_{0.0F};
|
||||
|
||||
// Subestat dins d'AIRBORNE: `enterHoleFall` el posa a true; mentre dura,
|
||||
// `integrateJump` no clampa `jump_z_` a 0 — deixa baixar a negatius i
|
||||
// dispara `enterDying()` quan creua `HOLE_FALL_DEPTH`. Es neteja a
|
||||
// `enterDying()` i `respawn()`.
|
||||
bool falling_through_hole_{false};
|
||||
|
||||
// Y absoluta (canvas píxels) per sota de la qual el `Player::render`
|
||||
// retalla el sprite mentre `falling_through_hole_=true`. La fixa
|
||||
// `enterHoleFall` a `floor_y - SPRITE_FLOOR_OFFSET` i la neteja
|
||||
// `respawn`. Sense ús quan no estem caient per un forat.
|
||||
float hole_clip_bottom_y_{0.0F};
|
||||
|
||||
// Profunditat (en píxels per sota del sòl) que ha de superar el jugador
|
||||
// mentre cau per un agujero abans que `integrateJump` el mate. Constant
|
||||
// per ara (ajustable a posteriori si el feel no és bo).
|
||||
static constexpr float HOLE_FALL_DEPTH = 20.0F;
|
||||
|
||||
// Píxels transparents a la base del sprite del jugador (16×32). El
|
||||
// sprite "camina pel mig del passadís en falsa perspectiva", així que
|
||||
// la silueta no toca la vora inferior del rect del sprite — hi queda
|
||||
// un marge transparent. Quan armem el clip rect del forat, restem
|
||||
// aquest offset a la `floor_y` perquè la línia de retall coincideixi
|
||||
// visualment amb la base del tile, no amb la vora del sprite.
|
||||
static constexpr float SPRITE_FLOOR_OFFSET = 3.0F;
|
||||
|
||||
// Temps restant de stun d'aterratge (ms). Mentre > 0, l'estat és
|
||||
// LANDING_STUN i tot l'input queda bloquejat.
|
||||
float landing_stun_remaining_ms_{0.0F};
|
||||
|
||||
Reference in new issue
Block a user