Animation API getting better but now need to resolve how it works with the frames.

This commit is contained in:
Zed A. Shaw 2026-01-30 23:26:35 -05:00
parent 785d0240da
commit d4e79f1d3d
7 changed files with 70 additions and 45 deletions

View file

@ -76,3 +76,6 @@ arena:
story: story:
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/storyboard 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"

View file

@ -4,7 +4,6 @@
#include "dbc.hpp" #include "dbc.hpp"
#include "rand.hpp" #include "rand.hpp"
namespace animate2 { namespace animate2 {
std::vector<sf::IntRect> Animate2::calc_frames() { std::vector<sf::IntRect> Animate2::calc_frames() {
std::vector<sf::IntRect> frames; std::vector<sf::IntRect> frames;
@ -53,7 +52,11 @@ namespace animate2 {
if($sequence.timer.getElapsedTime() >= duration) { if($sequence.timer.getElapsedTime() >= duration) {
$sequence.timer.restart(); $sequence.timer.restart();
$sequence.current++; $sequence.current++;
if($sequence.subframe > 0.9) $sequence.subframe = 0.0f;
frame_change = true; 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) { if($sequence.current >= $sequence.frame_count) {
@ -67,12 +70,19 @@ namespace animate2 {
} }
void Animate2::update() { void Animate2::update() {
$sequence.subframe += $transform.speed; // $sequence.subframe += $transform.speed;
update_frame(); update_frame();
} }
void Animate2::motion(sf::Vector2f& pos, sf::Vector2f& scale, float alpha) { void Animate2::motion(sf::Sprite& sprite, sf::Vector2f pos, sf::Vector2f scale) {
$transform.lerp($sequence, pos, scale, alpha); $transform.lerp($sequence, pos, scale);
sprite.setPosition(pos);
sprite.setScale(scale);
}
std::pair<int, double> Animate2::commit() {
return $sequence.timer.commit();
} }
void Timer::start() { void Timer::start() {
@ -118,12 +128,14 @@ namespace animate2 {
return {int(tick_count), alpha}; return {int(tick_count), alpha};
} }
float Transform::twitching(Sequence& seq, float alpha) { void Transform::lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out) {
return easing(alpha); // 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) { motion(*this, pos_out, scale_out, tick);
float tick = std::abs(twitching(seq, alpha));
return 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);
} }
} }

View file

@ -64,8 +64,7 @@ namespace animate2 {
ease2::EaseFunc easing = ease2::in_out_back; ease2::EaseFunc easing = ease2::in_out_back;
ease2::MoveFunc motion = ease2::move_rush; ease2::MoveFunc motion = ease2::move_rush;
float twitching(Sequence& seq, float alph); void lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out);
void lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float alpha);
}; };
/* Gets the number of times it looped, and returns if it should stop. */ /* 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 apply(sf::Sprite& sprite);
void update_frame(); void update_frame();
void update(); 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<int, double> commit();
}; };
} }

View file

@ -69,11 +69,11 @@ namespace ease2 {
} }
void scale_squeeze(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { 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) { 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) { void scale_stretch(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) {

View file

@ -12,6 +12,7 @@ cpp_args=[
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-Wno-unused-function', '-Wno-unused-function',
'-Wno-unused-variable', '-Wno-unused-variable',
'-Wno-unused-but-set-variable',
] ]
link_args=[] link_args=[]
# these are passed as override_defaults # these are passed as override_defaults

View file

@ -160,11 +160,11 @@ TEST_CASE("confirm transition changes work", "[animation-new]") {
textures::init(); textures::init();
animation::init(); animation::init();
auto sprite = *textures::get_sprite("rat_king_boss").sprite;
auto pos = sprite.getPosition();
auto scale = sprite.getScale();
auto anim = crafter(); 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 // also testing that onFrame being null means it's not run
REQUIRE(anim.onFrame == nullptr); REQUIRE(anim.onFrame == nullptr);
@ -175,12 +175,12 @@ TEST_CASE("confirm transition changes work", "[animation-new]") {
sf::Time start; sf::Time start;
sf::Time delta; sf::Time delta;
while(anim.playing) { while(anim.playing) {
start = clock.getElapsedTime(); start = clock.getElapsedTime();
anim.update(); anim.update();
anim.motion(pos, scale, 0.8f); anim.motion(sprite, pos, scale);
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
fmt::println("POSITION: {},{}; SCALE: {},{}; current: {}; subframe: {}", fmt::println("POSITION: {},{}; SCALE: {},{}; current: {}; subframe: {}",
pos.x, pos.y, scale.x, scale.y, anim.$sequence.current, anim.$sequence.subframe); pos.x, pos.y, scale.x, scale.y, anim.$sequence.current, anim.$sequence.subframe);

View file

@ -156,15 +156,15 @@ animate2::Sheet sheet{
}; };
animate2::Sequence sequence{ animate2::Sequence sequence{
.frames{0,1}, .frames{0,1,0,1},
.durations{166ms, 266ms} .durations{166ms, 266ms, 166ms, 266ms}
}; };
animate2::Transform transform{ animate2::Transform scale_tr{
.min_x{-20.0f}, .min_x{0.6f},
.min_y{-20.0f}, .min_y{0.6f},
.max_x{20.0f}, .max_x{0.8f},
.max_y{20.0f}, .max_y{0.8f},
.simple{false}, .simple{false},
.flipped{false}, .flipped{false},
.ease_rate{0.5f}, .ease_rate{0.5f},
@ -173,8 +173,25 @@ animate2::Transform transform{
.stationary{true}, .stationary{true},
.toggled{false}, .toggled{false},
.looped{true}, .looped{true},
.easing = ease2::out_bounce, .easing = ease2::out_circle,
.motion = ease2::move_bounce, .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[]) { int main(int argc, char* argv[]) {
@ -194,35 +211,27 @@ int main(int argc, char* argv[]) {
animator::FSM main; animator::FSM main;
main.init(argv[1]); main.init(argv[1]);
animate2::Animate2 anim{sheet, sequence, transform}; animate2::Animate2 anim{sheet, sequence, scale_tr};
animate2::Timer timer;
timer.start();
anim.play(); anim.play();
auto sprite = main.$ui.get_sprite(); 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()) { while(main.active()) {
auto [ticks, alpha] = timer.commit(); auto [ticks, alpha] = anim.commit();
fmt::println("TICK: {}, alpha: {}", ticks, alpha);
for(int i = 0; i < ticks; i++) { for(int i = 0; i < ticks; i++) {
main.event(game::Event::TICK, {}); main.event(game::Event::TICK, {});
anim.update(); anim.update();
}
anim.apply(*sprite); anim.apply(*sprite);
anim.motion(*sprite, pos, scale);
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(); main.render();
// do something with alpha....
main.handle_keyboard_mouse(); main.handle_keyboard_mouse();
} }