feat(anim): cardinal WEST i flip totalment governat pel motor d'animació
This commit is contained in:
1 parent
9dc7ff0da3
commit
72384c3113
15 files changed
+183
-182
No files matched your search
@@ -93,14 +93,13 @@ void AnimatedSprite::animate(float delta_time) {
|
||||
|
||||
const float TOTAL = std::accumulate(anim.speeds.begin(), anim.speeds.end(), 0.0F);
|
||||
|
||||
// Helper local per a propagar el frame actual (clip + opcionalment flip)
|
||||
// al sprite. El flip només s'escriu si l'animació declara `controls_flip`,
|
||||
// per a no trepitjar el flip que el codi del joc encara controla
|
||||
// externament en animacions sense declaració de flip al YAML.
|
||||
// Helper local per a propagar el frame actual (clip + flip) al sprite.
|
||||
// El motor sempre sobreescriu el flip — si el YAML no declara `flip_h`/
|
||||
// `flip_v`, el frame té els flags a false i el resultat és `SDL_FLIP_NONE`.
|
||||
auto apply_current_frame = [&](int frame_index) {
|
||||
const auto& frame = anim.frames[frame_index];
|
||||
setClip(frame.rect);
|
||||
if (anim.controls_flip) { setFlip(toFlipMode(frame.flip_h, frame.flip_v)); }
|
||||
setFlip(toFlipMode(frame.flip_h, frame.flip_v));
|
||||
};
|
||||
|
||||
if (anim.accumulated_time >= TOTAL) {
|
||||
@@ -151,7 +150,7 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name) {
|
||||
anim.completed = false;
|
||||
if (!anim.frames.empty()) {
|
||||
setClip(anim.frames[0].rect);
|
||||
if (anim.controls_flip) { setFlip(toFlipMode(anim.frames[0].flip_h, anim.frames[0].flip_v)); }
|
||||
setFlip(toFlipMode(anim.frames[0].flip_h, anim.frames[0].flip_v));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,13 @@ class AnimatedSprite : public MovingSprite {
|
||||
// Dades d'una animació concreta dins d'un spritesheet. Les claus del
|
||||
// mapa (`animations_`) són els noms; aquí només es guarden els fotogrames
|
||||
// i l'estat de reproducció.
|
||||
//
|
||||
// El flip és sempre propietat del motor: a cada `animate()` s'escriu el
|
||||
// flip del frame actual al sprite (default `SDL_FLIP_NONE` quan el YAML
|
||||
// no declara res). El codi del joc no pot — ni ha de — tocar el flip
|
||||
// manualment; ho expressa al YAML declarant `flip_h: true` a l'animació
|
||||
// simètrica (p. ex. `walk_west`) o, per a casos puntuals, per frame
|
||||
// amb la forma mapping `{ index, flip_h?, flip_v? }`.
|
||||
struct AnimationData {
|
||||
std::vector<Frame> frames;
|
||||
// Durada de cada frame en segons (convertit des de `frame_ms` al YAML).
|
||||
@@ -44,13 +51,6 @@ class AnimatedSprite : public MovingSprite {
|
||||
// 0 = loop complet des del primer frame.
|
||||
// N>0 = rebota al frame N en passar del final.
|
||||
int loop_from{0};
|
||||
// Si true, `animate()` escriu el flip del frame actual al sprite.
|
||||
// Si false (cas backward-compat per a animacions sense cap declaració
|
||||
// de flip), `animate()` no toca el flip — el codi del joc el segueix
|
||||
// controlant externament via `setFlip(...)`. Es marca a true quan
|
||||
// l'animació declara `flip_h`/`flip_v`, o quan algun frame es declara
|
||||
// amb la forma mapping `{ index, flip_h?, flip_v? }`.
|
||||
bool controls_flip{false};
|
||||
bool completed{false};
|
||||
int current_frame{0};
|
||||
float accumulated_time{0.0F};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
|
||||
#include "core/rendering/sprite/animated_sprite.hpp"
|
||||
|
||||
// Implementació del parser pure de YAML d'animacions. Viu en una unitat
|
||||
@@ -53,16 +50,6 @@ namespace {
|
||||
return frames;
|
||||
}
|
||||
|
||||
// Detecta si dins de `frames_node` hi ha algun element en forma mapping.
|
||||
// Si n'hi ha (encara que els flags interns siguin false), l'animació
|
||||
// passa a controlar el flip — el mapping és senyal explícit que l'autor
|
||||
// del YAML vol governar el flip per frame.
|
||||
auto framesContainMapping(const fkyaml::node& frames_node) -> bool {
|
||||
return std::ranges::any_of(frames_node, [](const auto& frame_node) {
|
||||
return frame_node.is_mapping();
|
||||
});
|
||||
}
|
||||
|
||||
// `frame_ms` pot ser un escalar (temps uniforme) o una llista (per-frame).
|
||||
// Convertim sempre a segons perquè `animate()` treballa amb delta_time
|
||||
// en segons. Si falta o val 0, `speeds` queda buit i l'animació es
|
||||
@@ -116,14 +103,7 @@ auto AnimatedSprite::parseAnimationsFromYaml(const fkyaml::node& yaml, const She
|
||||
|
||||
AnimationData animation;
|
||||
if (anim_node.contains("frames") && anim_node["frames"].is_sequence()) {
|
||||
const auto& frames_node = anim_node["frames"];
|
||||
animation.frames = convertYamlFrames(frames_node, params, anim_flip_h, anim_flip_v);
|
||||
// L'animació passa a "controlar" el flip si l'autor ha
|
||||
// declarat qualsevol cosa relacionada amb flip — sigui a
|
||||
// nivell d'anim o a través d'un frame en forma mapping.
|
||||
// Sense cap declaració, ens mantenim passius i deixem el
|
||||
// flip al codi del joc (backward-compat amb sam.yaml).
|
||||
animation.controls_flip = anim_flip_h || anim_flip_v || framesContainMapping(frames_node);
|
||||
animation.frames = convertYamlFrames(anim_node["frames"], params, anim_flip_h, anim_flip_v);
|
||||
}
|
||||
parseFrameTimes(anim_node, animation);
|
||||
parseLoopPolicy(anim_node, animation);
|
||||
|
||||
Reference in new issue
Block a user