From ba966aa7bf234c6c9f86eaec350451d08c3987be Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 20 Jan 2026 23:45:41 -0500 Subject: [PATCH] Animation now applies frame data to sprites. --- tests/animation.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/tests/animation.cpp b/tests/animation.cpp index f54d92d..cd191c3 100644 --- a/tests/animation.cpp +++ b/tests/animation.cpp @@ -21,7 +21,7 @@ struct Sheet { }; struct Sequence { - std::vector frames{}; + std::vector frames{}; std::vector durations{}; size_t current{0}; int loop_count{0}; @@ -63,9 +63,24 @@ class Animate2 { Sheet $sheet; Sequence $sequence; Transform $transform; + std::vector $frame_rects{calc_frames()}; OnLoopHandler onLoop = DefaultOnLoop; bool playing = false; + std::vector calc_frames() { + std::vector 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() { dbc::check(!playing, "can't call play while playing?"); $sequence.current = 0; @@ -80,7 +95,12 @@ class Animate2 { } // 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) { + 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 @@ -88,7 +108,7 @@ class Animate2 { 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()"); - auto duration = $sequence.durations[$sequence.current]; + auto duration = $sequence.durations.at($sequence.current); if($sequence.timer.getElapsedTime() >= duration) { $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(); animation::init(); @@ -219,12 +278,12 @@ TEST_CASE("apply animation works", "[animation-new]") { } REQUIRE(anim.playing == false); + REQUIRE(blanket.sprite->getPosition() != sf::Vector2f{0,0}); REQUIRE(pos != sf::Vector2f{0,0}); } - TEST_CASE("animation easing tests", "[animation]") { Animation anim;