feat(mummy): SPAWN dirigit per l'animació raise
This commit is contained in:
1 parent
8c84892250
commit
cba46642c6
7 files changed
+60
-28
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.9 KiB |
@@ -36,18 +36,17 @@ animations:
|
|||||||
walk_north: { frames: [4, 5, 6, 7], fps: 8, loop: true }
|
walk_north: { frames: [4, 5, 6, 7], fps: 8, loop: true }
|
||||||
walk_east: { frames: [8, 9, 10, 11], fps: 8, loop: true }
|
walk_east: { frames: [8, 9, 10, 11], fps: 8, loop: true }
|
||||||
walk_west: { frames: [8, 9, 10, 11], fps: 8, loop: true, flip_h: true }
|
walk_west: { frames: [8, 9, 10, 11], fps: 8, loop: true, flip_h: true }
|
||||||
|
raise: { frames: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27], fps: 8 , loop: false }
|
||||||
ai:
|
ai:
|
||||||
type: corridor_wanderer
|
type: corridor_wanderer
|
||||||
direction_choice: random
|
direction_choice: random
|
||||||
initial_direction: east
|
initial_direction: east
|
||||||
|
|
||||||
# Estat SPAWN: la mòmia s'instancia visible al pixel_rect_ inicial just
|
# Estat SPAWN: la mòmia s'instancia al pixel_rect_ inicial quan
|
||||||
# quan GameScene crida `spawnPendingActors()` (a la subfase text-exit
|
# GameScene crida `spawnPendingActors()` (subfase text-exit de
|
||||||
# de ROOM_INTRO, fase 4). El `triggerSpawnExit` es dispara llavors
|
# ROOM_INTRO, fase 4) amb l'animació `raise` activa. La duració del
|
||||||
# mateix; passats `duration_s` segons transita a ROAMING i empieza a
|
# SPAWN la marca la pròpia animació (no-loop): al `completed()`,
|
||||||
# deambular. Sense aquest bloc, default 0 ⇒ ACTIVE immediat.
|
# transita a ROAMING i comença a deambular.
|
||||||
spawn:
|
|
||||||
duration_s: 1.0
|
|
||||||
stats:
|
stats:
|
||||||
speed: 30
|
speed: 30
|
||||||
damage: 1
|
damage: 1
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ Mummy::Mummy(const fkyaml::node& yaml)
|
|||||||
: anim_walk_south_(buildAnimation(yaml, "walk_south")),
|
: anim_walk_south_(buildAnimation(yaml, "walk_south")),
|
||||||
anim_walk_north_(buildAnimation(yaml, "walk_north")),
|
anim_walk_north_(buildAnimation(yaml, "walk_north")),
|
||||||
anim_walk_east_(buildAnimation(yaml, "walk_east")),
|
anim_walk_east_(buildAnimation(yaml, "walk_east")),
|
||||||
anim_walk_west_(buildAnimation(yaml, "walk_west")) {
|
anim_walk_west_(buildAnimation(yaml, "walk_west")),
|
||||||
|
anim_raise_(buildAnimation(yaml, "raise")) {
|
||||||
name_ = yaml.contains("name") ? yaml["name"].get_value<std::string>() : std::string("mummy");
|
name_ = yaml.contains("name") ? yaml["name"].get_value<std::string>() : std::string("mummy");
|
||||||
collides_ = true;
|
collides_ = true;
|
||||||
interactable_ = false;
|
interactable_ = false;
|
||||||
@@ -141,16 +142,18 @@ Mummy::Mummy(const fkyaml::node& yaml)
|
|||||||
changeDirection(0.0F, 1.0F);
|
changeDirection(0.0F, 1.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Estat SPAWN inicial: la mòmia naix visible i quieta, esperant que el
|
// Estat SPAWN inicial: la mòmia naix en SPAWNING amb l'animació
|
||||||
// GameScene li armi el comptador via `triggerSpawnExit()` (cridat al
|
// `raise` activa (16 frames @ 8fps, no-loop). La duració del SPAWN
|
||||||
// final de la subfase text-exit de ROOM_INTRO). Si el YAML no declara
|
// la marca la pròpia animació — `Mummy::update` la tickeja, i quan
|
||||||
// `spawn.duration_s`, default 0 ⇒ al primer update post-trigger passa
|
// `completed()`, crida `endSpawn()` i restaura la `walk_*` per la
|
||||||
// directament a ACTIVE.
|
// direcció actual. Passem 0 al countdown del DynamicHazard perquè
|
||||||
float spawn_duration_s = 0.0F;
|
// no s'utilitza en aquest cas (el nostre `update` retorna abans).
|
||||||
if (yaml.contains("spawn") && yaml["spawn"].contains("duration_s")) {
|
enterSpawn(0.0F);
|
||||||
spawn_duration_s = yaml["spawn"]["duration_s"].get_value<float>();
|
anim_ = anim_raise_;
|
||||||
|
if (anim_.has_value()) {
|
||||||
|
anim_->reset();
|
||||||
|
flip_ = anim_->flipMode();
|
||||||
}
|
}
|
||||||
enterSpawn(spawn_duration_s);
|
|
||||||
|
|
||||||
// Configuració de l'estat HURT: opcional. Si el bloc no apareix, la
|
// Configuració de l'estat HURT: opcional. Si el bloc no apareix, la
|
||||||
// mòmia no entrarà mai a HURT efectiu (defensiu); el WhipAttack la
|
// mòmia no entrarà mai a HURT efectiu (defensiu); el WhipAttack la
|
||||||
@@ -692,6 +695,21 @@ void Mummy::hurtStep(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mummy::update(float delta_time) {
|
void Mummy::update(float delta_time) {
|
||||||
|
if (isSpawning()) {
|
||||||
|
// SPAWN dirigit per animació: la `raise` és no-loop, així que
|
||||||
|
// `completed()` ens marca el final. Mentre dura, NO cridem
|
||||||
|
// `DynamicHazard::update`: la base hi té el countdown i ja
|
||||||
|
// hauria saltat a ACTIVE (passem `enterSpawn(0)`), i el `step()`
|
||||||
|
// d'IA mouria la mòmia abans de "aixecar-se". En completar,
|
||||||
|
// tornem a la `walk_*` que toca segons la direcció ja triada
|
||||||
|
// al ctor (initial_direction de l'IA).
|
||||||
|
if (anim_.has_value()) { anim_->tick(delta_time); }
|
||||||
|
if (anim_.has_value() && anim_->completed()) {
|
||||||
|
endSpawn();
|
||||||
|
changeDirection(getDirX(), getDirY());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (state_ == State::HURT) {
|
if (state_ == State::HURT) {
|
||||||
// Avancem l'animació inline (no podem cridar `Entity::update` ni
|
// Avancem l'animació inline (no podem cridar `Entity::update` ni
|
||||||
// `DynamicHazard::update`: el primer salta una capa virtual i el
|
// `DynamicHazard::update`: el primer salta una capa virtual i el
|
||||||
|
|||||||
@@ -177,6 +177,12 @@ class Mummy : public DynamicHazard {
|
|||||||
AnimationComponent anim_walk_east_;
|
AnimationComponent anim_walk_east_;
|
||||||
AnimationComponent anim_walk_west_;
|
AnimationComponent anim_walk_west_;
|
||||||
|
|
||||||
|
// Animació d'aparició (no-loop). Mentre `isSpawning()`, `update()`
|
||||||
|
// la tickeja sense moure la mòmia; quan `completed()`, la mòmia
|
||||||
|
// transita a ACTIVE via `endSpawn()` i conmuta a la walk_* que
|
||||||
|
// toca segons direcció.
|
||||||
|
AnimationComponent anim_raise_;
|
||||||
|
|
||||||
// Estat HURT i la seua configuració. `hurt_speed_` és l'efectiva
|
// Estat HURT i la seua configuració. `hurt_speed_` és l'efectiva
|
||||||
// (resultat d'aplicar el `speed` del bloc `hurt:` o, si val 0, la
|
// (resultat d'aplicar el `speed` del bloc `hurt:` o, si val 0, la
|
||||||
// velocitat normal de la mòmia).
|
// velocitat normal de la mòmia).
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ class DynamicHazard : public Hazard {
|
|||||||
// Arma el comptador del SPAWN. A partir d'aquí, cada `update(dt)`
|
// Arma el comptador del SPAWN. A partir d'aquí, cada `update(dt)`
|
||||||
// descompta `dt` fins arribar a 0 i transitar a ACTIVE.
|
// descompta `dt` fins arribar a 0 i transitar a ACTIVE.
|
||||||
void triggerSpawnExit() { spawn_exit_armed_ = true; }
|
void triggerSpawnExit() { spawn_exit_armed_ = true; }
|
||||||
|
// Transició directa a ACTIVE, sense passar pel countdown. Pensat
|
||||||
|
// per a subclasses amb SPAWN dirigit per animació: gestionen el
|
||||||
|
// seu propi `update()` mentre `isSpawning()` i criden ací quan la
|
||||||
|
// seua animació d'aparició ha completat.
|
||||||
|
void endSpawn() { spawn_state_ = SpawnState::ACTIVE; }
|
||||||
[[nodiscard]] auto isSpawning() const -> bool { return spawn_state_ == SpawnState::SPAWNING; }
|
[[nodiscard]] auto isSpawning() const -> bool { return spawn_state_ == SpawnState::SPAWNING; }
|
||||||
[[nodiscard]] auto getSpawnDurationS() const -> float { return spawn_duration_s_; }
|
[[nodiscard]] auto getSpawnDurationS() const -> float { return spawn_duration_s_; }
|
||||||
|
|
||||||
|
|||||||
@@ -69,13 +69,14 @@ namespace {
|
|||||||
|
|
||||||
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
||||||
|
|
||||||
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra).
|
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra
|
||||||
// Equival al que fa GameScene al final del text-exit de ROOM_INTRO: arma
|
// amb l'animació `raise` activa). Tickem amb dt gran fins sortir de
|
||||||
// el comptador i consumeix la durada amb un update. Tests que operin
|
// SPAWNING — mateix path que `Mummy::update` executa al final de
|
||||||
// directament sobre HURT/ROAMING l'han de cridar abans.
|
// l'animació en partida real. El for limita el bucle defensivament.
|
||||||
void exitMummySpawn(Mummy& mummy) {
|
void exitMummySpawn(Mummy& mummy) {
|
||||||
mummy.triggerSpawnExit();
|
for (int i = 0; i < 32 && mummy.isSpawning(); ++i) {
|
||||||
mummy.update(mummy.getSpawnDurationS() + 0.001F);
|
mummy.update(0.5F);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void testFactory() {
|
void testFactory() {
|
||||||
|
|||||||
@@ -32,12 +32,15 @@ namespace {
|
|||||||
|
|
||||||
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
||||||
|
|
||||||
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra). Els
|
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra
|
||||||
// tests del whip necessiten que la mòmia estigui ACTIVE per reaccionar
|
// amb l'animació `raise` activa). Els tests del whip necessiten que la
|
||||||
// al fueteig — sense això, `enterHurt` torna early per `isSpawning()`.
|
// mòmia estigui ACTIVE per reaccionar al fueteig — sense això,
|
||||||
|
// `enterHurt` torna early per `isSpawning()`. Tickem amb dt gran fins
|
||||||
|
// sortir de SPAWNING (mateix path real, només accelerat).
|
||||||
void exitMummySpawn(Mummy& mummy) {
|
void exitMummySpawn(Mummy& mummy) {
|
||||||
mummy.triggerSpawnExit();
|
for (int i = 0; i < 32 && mummy.isSpawning(); ++i) {
|
||||||
mummy.update(mummy.getSpawnDurationS() + 0.001F);
|
mummy.update(0.5F);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Caja de jugador "estàndard" AEE: 16×32 amb cantonada (x, y).
|
// Caja de jugador "estàndard" AEE: 16×32 amb cantonada (x, y).
|
||||||
|
|||||||
Reference in new issue
Block a user