Animation now applies frame data to sprites.
This commit is contained in:
parent
d65883fa03
commit
ba966aa7bf
1 changed files with 63 additions and 4 deletions
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue