feat(player): gir de 180° amb pose intermèdia configurable al YAML
This commit is contained in:
1 parent
5c70019eb5
commit
74dad71cc2
5 files changed
+215
-56
No files matched your search
@@ -23,7 +23,8 @@ class Player : public AnimatedSprite {
|
||||
SDL_Scancode right;
|
||||
};
|
||||
|
||||
// Geometria carregada des de `data/player/player.yaml`. `sprite_*` són
|
||||
// Geometria carregada des del YAML del player (p.ex. `data/player/sam.yaml`).
|
||||
// `sprite_*` són
|
||||
// la mida del frame (sprite 12×24 amb perspectiva falsa: visualment, els
|
||||
// 12 píxels superiors són el cap i els 12 inferiors la base).
|
||||
// La caixa de col·lisió és un quadrat `collision_size` concèntric amb el
|
||||
@@ -121,6 +122,52 @@ class Player : public AnimatedSprite {
|
||||
DOWN };
|
||||
Facing facing_{Facing::SIDE};
|
||||
|
||||
// Cardinal complet (N/S/E/W) usat per a la detecció de girs de 180°.
|
||||
// El parell (Facing, flip) només té 3+1 estats; aquesta enum n'afegeix
|
||||
// la 4a sense reorganitzar el sistema d'animacions.
|
||||
enum class Cardinal : std::uint8_t { NONE,
|
||||
NORTH,
|
||||
SOUTH,
|
||||
EAST,
|
||||
WEST };
|
||||
|
||||
// Configuració del gir de 180°, llegida del bloc `turn:` del YAML del
|
||||
// player. Si `duration_ms` és 0 (o el bloc no existeix) la mecànica
|
||||
// queda desactivada i els canvis de direcció són instantanis.
|
||||
struct TurnConfig {
|
||||
int duration_ms{0};
|
||||
Cardinal w_to_e{Cardinal::SOUTH};
|
||||
Cardinal e_to_w{Cardinal::NORTH};
|
||||
Cardinal n_to_s{Cardinal::EAST};
|
||||
Cardinal s_to_n{Cardinal::WEST};
|
||||
};
|
||||
// Definida out-of-class al .cpp: dins de la classe, els initializers
|
||||
// per defecte de TurnConfig encara no són visibles per al compilador.
|
||||
static TurnConfig turn_config;
|
||||
|
||||
// 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,
|
||||
// s'aplica `pending_cardinal_`. `last_input_cardinal_` recorda l'últim
|
||||
// cardinal d'input no nul: serveix per disparar el gir només quan
|
||||
// l'usuari canvia d'opinió, no la primera vegada que prem una tecla
|
||||
// des de l'estat idle.
|
||||
float turning_remaining_ms_{0.0F};
|
||||
Cardinal pending_cardinal_{Cardinal::NONE};
|
||||
Cardinal intermediate_cardinal_{Cardinal::NONE};
|
||||
Cardinal last_input_cardinal_{Cardinal::NONE};
|
||||
|
||||
// Aplica un cardinal a (`facing_`, flip). NONE no fa res — preserva el
|
||||
// facing actual (cas idle: l'última orientació es manté).
|
||||
void applyCardinal(Cardinal c);
|
||||
// Actualitza facing_/flip i l'estat del gir a partir de l'input del frame.
|
||||
// Extret de `update` per acotar la complexitat cognitiva (clang-tidy).
|
||||
void updateFacingAndTurn(float delta_time, float vx, float vy);
|
||||
static auto cardinalFromInput(float vx, float vy) -> Cardinal;
|
||||
static auto cardinalFromString(const std::string& s) -> Cardinal;
|
||||
static auto opposite(Cardinal c) -> Cardinal;
|
||||
static auto intermediateFor(Cardinal target) -> Cardinal;
|
||||
|
||||
// Bus del nivell (opcional). Propietat externa (EntityManager); el
|
||||
// Player només en guarda un punter per publicar events.
|
||||
EventBus* bus_{nullptr};
|
||||
|
||||
Reference in new issue
Block a user