Added an onFrame callback that only is called when a frame change happens.

This commit is contained in:
Zed A. Shaw 2026-01-21 00:06:39 -05:00
parent ba966aa7bf
commit 992b8f0e0a

View file

@ -52,6 +52,7 @@ struct Transform {
/* Gets the number of times it looped, and returns if it should stop. */
using OnLoopHandler = std::function<bool(Sequence& seq, Transform& tr)>;
using OnFrameHandler = std::function<void()>;
bool DefaultOnLoop(Sequence& seq, Transform& tr) {
seq.current = 0;
@ -63,6 +64,8 @@ class Animate2 {
Sheet $sheet;
Sequence $sequence;
Transform $transform;
OnFrameHandler onFrame = nullptr;
std::vector<sf::IntRect> $frame_rects{calc_frames()};
OnLoopHandler onLoop = DefaultOnLoop;
bool playing = false;
@ -109,10 +112,12 @@ class Animate2 {
dbc::check($sequence.frame_count == $sequence.frames.size(), "frame_count doesn't match frame.size()");
auto duration = $sequence.durations.at($sequence.current);
bool frame_change = false;
if($sequence.timer.getElapsedTime() >= duration) {
$sequence.timer.restart();
$sequence.current++;
frame_change = true;
}
if($sequence.current >= $sequence.frame_count) {
@ -120,7 +125,9 @@ class Animate2 {
playing = onLoop($sequence, $transform);
}
dbc::check($sequence.current < $sequence.frame_count, "current frame out of frames.size()");
if(frame_change && onFrame != nullptr) onFrame();
dbc::check($sequence.current < $sequence.frame_count, "onLoop fail: current frame out of frames.size()");
}
void update() {
@ -240,21 +247,22 @@ TEST_CASE("confirm frame sequencing works", "[animation-new]") {
anim.onLoop = [&](auto& seq, auto& tr) -> bool {
seq.current = 0;
loop_ran = true;
REQUIRE(blanket.sprite->getTextureRect() != init_rect);
return false;
};
anim.onFrame = [&](){
anim.apply(*blanket.sprite, {});
};
sf::Vector2f pos{0,0};
while(anim.playing) {
anim.update();
// NOTE: possibly find a way to only run apply on frame change?
anim.apply(*blanket.sprite, pos);
}
// NOTE: might need one final apply call to go to frame 0?
anim.apply(*blanket.sprite, pos);
REQUIRE(loop_ran == true);
REQUIRE(anim.playing == false);