fix(mummy): evita soft-lock per drift sub-pixel a HURT vora del mur
This commit is contained in:
1 parent
0d58da536c
commit
e9f99a0542
2 files changed
+128
-5
No files matched your search
@@ -222,9 +222,24 @@ void Mummy::step(float delta_time) {
|
||||
const float DX = dir_x_ * speed_ * delta_time;
|
||||
const float DY = dir_y_ * speed_ * delta_time;
|
||||
|
||||
// Si no té direcció (p.ex. YAML sense `initial_direction`), el frame és
|
||||
// no-op fins que algú la injecte amb `setDirection`.
|
||||
if (DX == 0.0F && DY == 0.0F) { return; }
|
||||
// Sense direcció: pot ser un setup degenerat (YAML sense
|
||||
// `initial_direction`) o el residu d'un HURT que va sortir amb
|
||||
// `chooseHurtDirection() == NONE` (totes les direccions provades
|
||||
// bloquejades). En aquest segon cas la mòmia quedaria eternament quieta
|
||||
// — `setDirection(0,0)` a `enterHurt` no toca `anim_`, així que es
|
||||
// veuria animant-se sense moure's. Re-decidim com a una intersecció:
|
||||
// si trobem alguna perpendicular vàlida, la prenem; si no, mitja volta.
|
||||
// Si tampoc, mantenim (0,0) i tornem a provar el proper frame —
|
||||
// pràcticament impossible amb la geometria actual, però no enganxa.
|
||||
if (DX == 0.0F && DY == 0.0F) {
|
||||
auto pools = collectDirectionPools(speed_ * delta_time, /*avoid_blocked=*/true);
|
||||
if (!pools.perp.empty()) {
|
||||
applyChoice(chooseDirection(pools.perp));
|
||||
} else if (!pools.uturn.empty()) {
|
||||
applyChoice(chooseDirection(pools.uturn));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Branca creuament: si aquest frame travessa la línia central d'un
|
||||
// corredor perpendicular, amarra la caixa al centre del creuament i
|
||||
@@ -612,8 +627,20 @@ void Mummy::hurtStep(float delta_time) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Topa amb mur o sarc: surt del HURT immediatament. La IA normal
|
||||
// re-decideix al pròxim step (no fem U-turn ni re-orientació aquí).
|
||||
// Topa amb mur del playfield: amarra la BOX a la vora exacta abans de
|
||||
// transitar a ROAMING. Sense aquest snap, el drift sub-pixel acumulat a
|
||||
// la cursa (DX = -hurt_speed·dt rarament és enter al joc real, on dt ve
|
||||
// de SDL_GetTicks) deixaria la BOX a un offset de 0.x px dins de
|
||||
// l'última cel·la. Com que la BOX és 16×16 i els passadissos també ho
|
||||
// són, qualsevol drift fa que la cantonada sobresurti cap als sarcs
|
||||
// adjacents — i el `chooseHurtDirection` del proper fueteig classifica
|
||||
// les perpendiculars com a bloquejades per micro-overlap, retornant
|
||||
// NONE i deixant la mòmia eternament quieta. Sarc-collision durant HURT
|
||||
// és un cas molt menys habitual (la cursa va sempre per corredor recte);
|
||||
// si arriba a passar, l'snap al playfield no l'arregla però la branca
|
||||
// de recovery a `step()` el cobreix.
|
||||
if (!Map::insidePlayfield(CANDIDATE)) { snapToPlayfieldEdge(DX, DY); }
|
||||
|
||||
state_ = State::ROAMING;
|
||||
hurt_remaining_s_ = 0.0F;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user