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_east: { frames: [8, 9, 10, 11], fps: 8, loop: 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:
|
||||
type: corridor_wanderer
|
||||
direction_choice: random
|
||||
initial_direction: east
|
||||
|
||||
# Estat SPAWN: la mòmia s'instancia visible al pixel_rect_ inicial just
|
||||
# quan GameScene crida `spawnPendingActors()` (a la subfase text-exit
|
||||
# de ROOM_INTRO, fase 4). El `triggerSpawnExit` es dispara llavors
|
||||
# mateix; passats `duration_s` segons transita a ROAMING i empieza a
|
||||
# deambular. Sense aquest bloc, default 0 ⇒ ACTIVE immediat.
|
||||
spawn:
|
||||
duration_s: 1.0
|
||||
# Estat SPAWN: la mòmia s'instancia al pixel_rect_ inicial quan
|
||||
# GameScene crida `spawnPendingActors()` (subfase text-exit de
|
||||
# ROOM_INTRO, fase 4) amb l'animació `raise` activa. La duració del
|
||||
# SPAWN la marca la pròpia animació (no-loop): al `completed()`,
|
||||
# transita a ROAMING i comença a deambular.
|
||||
stats:
|
||||
speed: 30
|
||||
damage: 1
|
||||
|
||||
@@ -106,7 +106,8 @@ Mummy::Mummy(const fkyaml::node& yaml)
|
||||
: anim_walk_south_(buildAnimation(yaml, "walk_south")),
|
||||
anim_walk_north_(buildAnimation(yaml, "walk_north")),
|
||||
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");
|
||||
collides_ = true;
|
||||
interactable_ = false;
|
||||
@@ -141,16 +142,18 @@ Mummy::Mummy(const fkyaml::node& yaml)
|
||||
changeDirection(0.0F, 1.0F);
|
||||
}
|
||||
|
||||
// Estat SPAWN inicial: la mòmia naix visible i quieta, esperant que el
|
||||
// GameScene li armi el comptador via `triggerSpawnExit()` (cridat al
|
||||
// final de la subfase text-exit de ROOM_INTRO). Si el YAML no declara
|
||||
// `spawn.duration_s`, default 0 ⇒ al primer update post-trigger passa
|
||||
// directament a ACTIVE.
|
||||
float spawn_duration_s = 0.0F;
|
||||
if (yaml.contains("spawn") && yaml["spawn"].contains("duration_s")) {
|
||||
spawn_duration_s = yaml["spawn"]["duration_s"].get_value<float>();
|
||||
// Estat SPAWN inicial: la mòmia naix en SPAWNING amb l'animació
|
||||
// `raise` activa (16 frames @ 8fps, no-loop). La duració del SPAWN
|
||||
// la marca la pròpia animació — `Mummy::update` la tickeja, i quan
|
||||
// `completed()`, crida `endSpawn()` i restaura la `walk_*` per la
|
||||
// direcció actual. Passem 0 al countdown del DynamicHazard perquè
|
||||
// no s'utilitza en aquest cas (el nostre `update` retorna abans).
|
||||
enterSpawn(0.0F);
|
||||
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
|
||||
// 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) {
|
||||
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) {
|
||||
// Avancem l'animació inline (no podem cridar `Entity::update` ni
|
||||
// `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_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
|
||||
// (resultat d'aplicar el `speed` del bloc `hurt:` o, si val 0, la
|
||||
// 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)`
|
||||
// descompta `dt` fins arribar a 0 i transitar a ACTIVE.
|
||||
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 getSpawnDurationS() const -> float { return spawn_duration_s_; }
|
||||
|
||||
|
||||
@@ -69,13 +69,14 @@ namespace {
|
||||
|
||||
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
||||
|
||||
// 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
|
||||
// el comptador i consumeix la durada amb un update. Tests que operin
|
||||
// directament sobre HURT/ROAMING l'han de cridar abans.
|
||||
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra
|
||||
// amb l'animació `raise` activa). Tickem amb dt gran fins sortir de
|
||||
// SPAWNING — mateix path que `Mummy::update` executa al final de
|
||||
// l'animació en partida real. El for limita el bucle defensivament.
|
||||
void exitMummySpawn(Mummy& mummy) {
|
||||
mummy.triggerSpawnExit();
|
||||
mummy.update(mummy.getSpawnDurationS() + 0.001F);
|
||||
for (int i = 0; i < 32 && mummy.isSpawning(); ++i) {
|
||||
mummy.update(0.5F);
|
||||
}
|
||||
}
|
||||
|
||||
void testFactory() {
|
||||
|
||||
@@ -32,12 +32,15 @@ namespace {
|
||||
|
||||
#define REQUIRE(cond) check((cond), #cond, __FILE__, __LINE__)
|
||||
|
||||
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra). Els
|
||||
// tests del whip necessiten que la mòmia estigui ACTIVE per reaccionar
|
||||
// al fueteig — sense això, `enterHurt` torna early per `isSpawning()`.
|
||||
// Treu la mòmia de l'estat SPAWN inicial (Mummy::Mummy ara hi entra
|
||||
// amb l'animació `raise` activa). Els tests del whip necessiten que la
|
||||
// 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) {
|
||||
mummy.triggerSpawnExit();
|
||||
mummy.update(mummy.getSpawnDurationS() + 0.001F);
|
||||
for (int i = 0; i < 32 && mummy.isSpawning(); ++i) {
|
||||
mummy.update(0.5F);
|
||||
}
|
||||
}
|
||||
|
||||
// Caja de jugador "estàndard" AEE: 16×32 amb cantonada (x, y).
|
||||
|
||||
Reference in new issue
Block a user