From d4e79f1d3d8eaa056ce46c32062c711c9dd63e3a Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Fri, 30 Jan 2026 23:26:35 -0500 Subject: [PATCH] Animation API getting better but now need to resolve how it works with the frames. --- Makefile | 3 +++ animate2.cpp | 32 +++++++++++++++++-------- animate2.hpp | 6 ++--- ease2.cpp | 4 ++-- meson.build | 1 + tests/animate2.cpp | 10 ++++---- tools/animator.cpp | 59 ++++++++++++++++++++++++++-------------------- 7 files changed, 70 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index 6a047a6..015f334 100644 --- a/Makefile +++ b/Makefile @@ -76,3 +76,6 @@ arena: story: gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/storyboard + +animator: + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/animator "rat_king_boss" diff --git a/animate2.cpp b/animate2.cpp index 2811e32..98a1d1f 100644 --- a/animate2.cpp +++ b/animate2.cpp @@ -4,7 +4,6 @@ #include "dbc.hpp" #include "rand.hpp" - namespace animate2 { std::vector Animate2::calc_frames() { std::vector frames; @@ -53,7 +52,11 @@ namespace animate2 { if($sequence.timer.getElapsedTime() >= duration) { $sequence.timer.restart(); $sequence.current++; + if($sequence.subframe > 0.9) $sequence.subframe = 0.0f; frame_change = true; + } else { + $sequence.subframe = std::lerp($sequence.subframe, 1.0, $sequence.timer.alpha * $transform.ease_rate); + fmt::println("subframe: {}, alpha: {}", $sequence.subframe, $sequence.timer.alpha); } if($sequence.current >= $sequence.frame_count) { @@ -67,12 +70,19 @@ namespace animate2 { } void Animate2::update() { - $sequence.subframe += $transform.speed; + // $sequence.subframe += $transform.speed; update_frame(); } - void Animate2::motion(sf::Vector2f& pos, sf::Vector2f& scale, float alpha) { - $transform.lerp($sequence, pos, scale, alpha); + void Animate2::motion(sf::Sprite& sprite, sf::Vector2f pos, sf::Vector2f scale) { + $transform.lerp($sequence, pos, scale); + + sprite.setPosition(pos); + sprite.setScale(scale); + } + + std::pair Animate2::commit() { + return $sequence.timer.commit(); } void Timer::start() { @@ -118,12 +128,14 @@ namespace animate2 { return {int(tick_count), alpha}; } - float Transform::twitching(Sequence& seq, float alpha) { - return easing(alpha); - } + void Transform::lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out) { + // float dt = 1 - std::powf(ease_rate, seq.subframe + 0.0001); + float tick = easing(seq.subframe); - void Transform::lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float alpha) { - float tick = std::abs(twitching(seq, alpha)); - return motion(*this, pos_out, scale_out, tick); + motion(*this, pos_out, scale_out, tick); + + fmt::println("sub: {}, tick: {}, tr: {},{}; pos: {},{}; scale: {},{}", + seq.subframe, tick, min_y, max_y, pos_out.x, pos_out.y, + scale_out.x, scale_out.y); } } diff --git a/animate2.hpp b/animate2.hpp index 1dfb800..d13d9e0 100644 --- a/animate2.hpp +++ b/animate2.hpp @@ -64,8 +64,7 @@ namespace animate2 { ease2::EaseFunc easing = ease2::in_out_back; ease2::MoveFunc motion = ease2::move_rush; - float twitching(Sequence& seq, float alph); - void lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float alpha); + void lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out); }; /* Gets the number of times it looped, and returns if it should stop. */ @@ -94,7 +93,8 @@ namespace animate2 { void apply(sf::Sprite& sprite); void update_frame(); void update(); - void motion(sf::Vector2f& pos_out, sf::Vector2f& scale_out, float alpha); + void motion(sf::Sprite& sprite, sf::Vector2f pos, sf::Vector2f scale); + std::pair commit(); }; } diff --git a/ease2.cpp b/ease2.cpp index 43e86ce..993e028 100644 --- a/ease2.cpp +++ b/ease2.cpp @@ -69,11 +69,11 @@ namespace ease2 { } void scale_squeeze(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { - scale_out.x *= std::lerp(tr.min_x, tr.max_x, tick); + scale_out.x = std::lerp(tr.min_x, tr.max_x, tick); } void scale_squash(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { - scale_out.y *= std::lerp(tr.min_y, tr.max_y, tick); + scale_out.y = std::lerp(tr.min_y, tr.max_y, tick); } void scale_stretch(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { diff --git a/meson.build b/meson.build index 2acac0e..7e0f14d 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,7 @@ cpp_args=[ '-Wno-unused-parameter', '-Wno-unused-function', '-Wno-unused-variable', + '-Wno-unused-but-set-variable', ] link_args=[] # these are passed as override_defaults diff --git a/tests/animate2.cpp b/tests/animate2.cpp index d52b237..a065067 100644 --- a/tests/animate2.cpp +++ b/tests/animate2.cpp @@ -160,11 +160,11 @@ TEST_CASE("confirm transition changes work", "[animation-new]") { textures::init(); animation::init(); + auto sprite = *textures::get_sprite("rat_king_boss").sprite; + auto pos = sprite.getPosition(); + auto scale = sprite.getScale(); auto anim = crafter(); - sf::Vector2f pos{10,10}; - sf::Vector2f scale{0.6, 0.6}; - // also testing that onFrame being null means it's not run REQUIRE(anim.onFrame == nullptr); @@ -175,12 +175,12 @@ TEST_CASE("confirm transition changes work", "[animation-new]") { sf::Time start; sf::Time delta; - while(anim.playing) { start = clock.getElapsedTime(); anim.update(); - anim.motion(pos, scale, 0.8f); + anim.motion(sprite, pos, scale); + std::this_thread::sleep_for(10ms); fmt::println("POSITION: {},{}; SCALE: {},{}; current: {}; subframe: {}", pos.x, pos.y, scale.x, scale.y, anim.$sequence.current, anim.$sequence.subframe); diff --git a/tools/animator.cpp b/tools/animator.cpp index 3646900..6da0ca9 100644 --- a/tools/animator.cpp +++ b/tools/animator.cpp @@ -156,15 +156,15 @@ animate2::Sheet sheet{ }; animate2::Sequence sequence{ - .frames{0,1}, - .durations{166ms, 266ms} + .frames{0,1,0,1}, + .durations{166ms, 266ms, 166ms, 266ms} }; -animate2::Transform transform{ - .min_x{-20.0f}, - .min_y{-20.0f}, - .max_x{20.0f}, - .max_y{20.0f}, +animate2::Transform scale_tr{ + .min_x{0.6f}, + .min_y{0.6f}, + .max_x{0.8f}, + .max_y{0.8f}, .simple{false}, .flipped{false}, .ease_rate{0.5f}, @@ -173,8 +173,25 @@ animate2::Transform transform{ .stationary{true}, .toggled{false}, .looped{true}, - .easing = ease2::out_bounce, - .motion = ease2::move_bounce, + .easing = ease2::out_circle, + .motion = ease2::move_rush, +}; + +animate2::Transform move_tr{ + .min_x{-20.0f}, + .min_y{-20.0f}, + .max_x{20.0f}, + .max_y{20.0f}, + .simple{false}, + .flipped{false}, + .ease_rate{2.5f}, + .speed{0.02f}, + .scaled{true}, + .stationary{true}, + .toggled{false}, + .looped{true}, + .easing = ease2::normal_dist, + .motion = ease2::move_shake, }; int main(int argc, char* argv[]) { @@ -194,35 +211,27 @@ int main(int argc, char* argv[]) { animator::FSM main; main.init(argv[1]); - animate2::Animate2 anim{sheet, sequence, transform}; - animate2::Timer timer; - timer.start(); + animate2::Animate2 anim{sheet, sequence, scale_tr}; anim.play(); auto sprite = main.$ui.get_sprite(); - sf::Vector2f pos = sprite->getPosition(); - sf::Vector2f scale = sprite->getScale(); + + // need to keep these aroung + auto pos = sprite->getPosition(); + auto scale = sprite->getScale(); while(main.active()) { - auto [ticks, alpha] = timer.commit(); - fmt::println("TICK: {}, alpha: {}", ticks, alpha); + auto [ticks, alpha] = anim.commit(); for(int i = 0; i < ticks; i++) { main.event(game::Event::TICK, {}); anim.update(); + anim.apply(*sprite); + anim.motion(*sprite, pos, scale); } - anim.apply(*sprite); - - sf::Vector2f new_pos = pos; - sf::Vector2f new_scale = scale; - anim.motion(new_pos, new_scale, alpha); - sprite->setPosition(new_pos); - sprite->setScale(new_scale); - main.render(); - // do something with alpha.... main.handle_keyboard_mouse(); }