Animation now applies frame data to sprites.

This commit is contained in:
Zed A. Shaw 2026-01-20 23:45:41 -05:00
parent d65883fa03
commit ba966aa7bf

View file

@ -21,7 +21,7 @@ struct Sheet {
}; };
struct Sequence { struct Sequence {
std::vector<size_t> frames{}; std::vector<int> frames{};
std::vector<std::chrono::milliseconds> durations{}; std::vector<std::chrono::milliseconds> durations{};
size_t current{0}; size_t current{0};
int loop_count{0}; int loop_count{0};
@ -63,9 +63,24 @@ class Animate2 {
Sheet $sheet; Sheet $sheet;
Sequence $sequence; Sequence $sequence;
Transform $transform; Transform $transform;
std::vector<sf::IntRect> $frame_rects{calc_frames()};
OnLoopHandler onLoop = DefaultOnLoop; OnLoopHandler onLoop = DefaultOnLoop;
bool playing = false; bool playing = false;
std::vector<sf::IntRect> calc_frames() {
std::vector<sf::IntRect> frames;
for(int frame_i : $sequence.frames) {
frames.emplace_back(
sf::Vector2i{$sheet.frame_width * frame_i, 0}, // NOTE: one row only for now
sf::Vector2i{$sheet.frame_width,
$sheet.frame_height});
}
return frames;
}
void play() { void play() {
dbc::check(!playing, "can't call play while playing?"); dbc::check(!playing, "can't call play while playing?");
$sequence.current = 0; $sequence.current = 0;
@ -80,7 +95,12 @@ class Animate2 {
} }
// need one for each kind of thing to animate // need one for each kind of thing to animate
// NOTE: possibly find a way to only run apply on frame change?
void apply(sf::Sprite& sprite, sf::Vector2f pos) { void apply(sf::Sprite& sprite, sf::Vector2f pos) {
dbc::check($sequence.current < $frame_rects.size(), "current frame past $frame_rects");
// NOTE: pos is not updated yet
auto& rect = $frame_rects.at($sequence.current);
sprite.setTextureRect(rect);
} }
// replaces step // replaces step
@ -88,7 +108,7 @@ class Animate2 {
dbc::check(playing, "attempt to update animation that's not playing"); dbc::check(playing, "attempt to update animation that's not playing");
dbc::check($sequence.frame_count == $sequence.frames.size(), "frame_count doesn't match frame.size()"); dbc::check($sequence.frame_count == $sequence.frames.size(), "frame_count doesn't match frame.size()");
auto duration = $sequence.durations[$sequence.current]; auto duration = $sequence.durations.at($sequence.current);
if($sequence.timer.getElapsedTime() >= duration) { if($sequence.timer.getElapsedTime() >= duration) {
$sequence.timer.restart(); $sequence.timer.restart();
@ -204,7 +224,46 @@ TEST_CASE("new animation system", "[animation-new]") {
}; };
} }
TEST_CASE("apply animation works", "[animation-new]") { TEST_CASE("confirm frame sequencing works", "[animation-new]") {
textures::init();
animation::init();
auto anim = crafter();
auto blanket = textures::get_sprite("ritual_crafting_area");
sf::IntRect init_rect{{0,0}, {anim.$sheet.frame_width, anim.$sheet.frame_height}};
anim.play();
bool loop_ran = false;
// this will check that it moved to the next frame
anim.onLoop = [&](auto& seq, auto& tr) -> bool {
seq.current = 0;
loop_ran = true;
REQUIRE(blanket.sprite->getTextureRect() != init_rect);
return false;
};
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);
// this confirms it went back to the first frame
REQUIRE(blanket.sprite->getTextureRect() == init_rect);
}
TEST_CASE("confirm transition changes work", "[animation-new]") {
return;
textures::init(); textures::init();
animation::init(); animation::init();
@ -219,12 +278,12 @@ TEST_CASE("apply animation works", "[animation-new]") {
} }
REQUIRE(anim.playing == false); REQUIRE(anim.playing == false);
REQUIRE(blanket.sprite->getPosition() != sf::Vector2f{0,0}); REQUIRE(blanket.sprite->getPosition() != sf::Vector2f{0,0});
REQUIRE(pos != sf::Vector2f{0,0}); REQUIRE(pos != sf::Vector2f{0,0});
} }
TEST_CASE("animation easing tests", "[animation]") { TEST_CASE("animation easing tests", "[animation]") {
Animation anim; Animation anim;