scenes: infraestructura de la capa scenes:: (scene, timeline, sprite mover, frame animator, palette fade, surface handle, registry)
This commit is contained in:
85
source/scenes/timeline.cpp
Normal file
85
source/scenes/timeline.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "scenes/timeline.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace scenes {
|
||||
|
||||
Timeline& Timeline::step(int duration_ms, StepFn fn) {
|
||||
Step s;
|
||||
s.duration_ms = duration_ms;
|
||||
s.continuous = std::move(fn);
|
||||
steps_.push_back(std::move(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Timeline& Timeline::once(OnceFn fn) {
|
||||
Step s;
|
||||
s.duration_ms = 0;
|
||||
s.oneshot = std::move(fn);
|
||||
steps_.push_back(std::move(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Timeline::flushOneShots() {
|
||||
while (current_ < steps_.size() && steps_[current_].duration_ms == 0) {
|
||||
auto& s = steps_[current_];
|
||||
if (!s.entered) {
|
||||
s.entered = true;
|
||||
if (s.oneshot) s.oneshot();
|
||||
}
|
||||
++current_;
|
||||
elapsed_in_step_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::tick(int delta_ms) {
|
||||
if (skipped_) return;
|
||||
flushOneShots();
|
||||
if (current_ >= steps_.size()) return;
|
||||
|
||||
auto& s = steps_[current_];
|
||||
if (!s.entered) {
|
||||
s.entered = true;
|
||||
// Primer tick dins del pas: cridem amb progress=0 si hi ha callback.
|
||||
if (s.continuous) s.continuous(0.0f);
|
||||
}
|
||||
|
||||
elapsed_in_step_ += delta_ms;
|
||||
if (elapsed_in_step_ >= s.duration_ms) {
|
||||
// Tancament del pas: una crida final amb progress=1.
|
||||
if (s.continuous) s.continuous(1.0f);
|
||||
++current_;
|
||||
elapsed_in_step_ = 0;
|
||||
// Pot ser que el següent pas siga una cadena de one-shots.
|
||||
flushOneShots();
|
||||
} else if (s.continuous) {
|
||||
const float p = static_cast<float>(elapsed_in_step_) /
|
||||
static_cast<float>(std::max(1, s.duration_ms));
|
||||
s.continuous(p);
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::skip() {
|
||||
skipped_ = true;
|
||||
current_ = steps_.size();
|
||||
}
|
||||
|
||||
void Timeline::reset() {
|
||||
for (auto& s : steps_) s.entered = false;
|
||||
current_ = 0;
|
||||
elapsed_in_step_ = 0;
|
||||
skipped_ = false;
|
||||
}
|
||||
|
||||
bool Timeline::done() const {
|
||||
return skipped_ || current_ >= steps_.size();
|
||||
}
|
||||
|
||||
float Timeline::currentProgress() const {
|
||||
if (current_ >= steps_.size()) return 1.0f;
|
||||
const auto& s = steps_[current_];
|
||||
if (s.duration_ms <= 0) return 0.0f;
|
||||
return static_cast<float>(elapsed_in_step_) / static_cast<float>(s.duration_ms);
|
||||
}
|
||||
|
||||
} // namespace scenes
|
||||
Reference in New Issue
Block a user