First cut of pulling out the relevant parts of my original game to make a little framework.
This commit is contained in:
commit
6a0c9e8d46
177 changed files with 18197 additions and 0 deletions
169
tests/animation.cpp
Normal file
169
tests/animation.cpp
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
#include "graphics/textures.hpp"
|
||||
#include "algos/dinkyecs.hpp"
|
||||
#include "game/config.hpp"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "algos/rand.hpp"
|
||||
#include "graphics/animation.hpp"
|
||||
#include "game/sound.hpp"
|
||||
#include "game/components.hpp"
|
||||
|
||||
using namespace components;
|
||||
using namespace textures;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace animation;
|
||||
|
||||
Animation load_animation(const string& name) {
|
||||
auto anim = animation::load("assets/animation.json", "rat_king_boss");
|
||||
anim.set_form("attack");
|
||||
|
||||
anim.transform.looped = false;
|
||||
|
||||
for(size_t i = 0; i < anim.sequence.durations.size(); i++) {
|
||||
anim.sequence.durations[i] = Random::uniform(1, 5);
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
void FAKE_RENDER() {
|
||||
std::this_thread::sleep_for(Random::milliseconds(5, 32));
|
||||
}
|
||||
|
||||
void PLAY_TEST(Animation &anim) {
|
||||
REQUIRE(anim.transform.looped == false);
|
||||
anim.play();
|
||||
|
||||
while(anim.playing) {
|
||||
anim.update();
|
||||
FAKE_RENDER();
|
||||
}
|
||||
|
||||
REQUIRE(anim.playing == false);
|
||||
}
|
||||
|
||||
// /*
|
||||
// * Animation is a Sheet + Sequence + Transform.
|
||||
// *
|
||||
// * A Sheet is just a grid of images with a predefined size for each cell. Arbitrary sized cells not supported.
|
||||
// *
|
||||
// * A Sequence is a list of Sheet cells _in any order_. See https://github.com/yottahmd/ganim8-lib. Sequences have a timing element for the cells, possibly a list of durations or a single duration.
|
||||
// *
|
||||
// * A Transform is combinations of scale and/or position easing/motion, shader effects, and things like if it's looped or toggled.
|
||||
// *
|
||||
// * I like the ganim8 onLoop concept, just a callback that says what to do when the animation has looped.
|
||||
// */
|
||||
// TEST_CASE("new animation system", "[animation-new]") {
|
||||
// textures::init();
|
||||
// sound::init();
|
||||
// sound::mute(true);
|
||||
//
|
||||
// auto anim = load_animation("rat_king_boss");
|
||||
// PLAY_TEST(anim);
|
||||
//
|
||||
// // test that toggled works
|
||||
// anim.transform.toggled = true;
|
||||
// PLAY_TEST(anim);
|
||||
// REQUIRE(anim.sequence.current == anim.sequence.frames.size() - 1);
|
||||
// anim.transform.toggled = false;
|
||||
//
|
||||
// bool onLoop_ran = false;
|
||||
// anim.onLoop = [&](auto& seq, auto& tr) -> bool {
|
||||
// seq.current = 0;
|
||||
// onLoop_ran = true;
|
||||
// return tr.looped;
|
||||
// };
|
||||
//
|
||||
// PLAY_TEST(anim);
|
||||
// REQUIRE(onLoop_ran == true);
|
||||
//
|
||||
// // only runs twice
|
||||
// anim.onLoop = [](auto& seq, auto& tr) -> bool {
|
||||
// if(seq.loop_count == 2) {
|
||||
// seq.current = 0;
|
||||
// return false;
|
||||
// } else {
|
||||
// seq.current = seq.current % seq.frame_count;
|
||||
// return true;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// PLAY_TEST(anim);
|
||||
// REQUIRE(anim.sequence.loop_count == 2);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// TEST_CASE("confirm frame sequencing works", "[animation-new]") {
|
||||
// textures::init();
|
||||
// sound::init();
|
||||
// sound::mute(true);
|
||||
//
|
||||
// auto anim = load_animation("rat_king_boss");
|
||||
//
|
||||
// auto boss = textures::get_sprite("rat_king_boss");
|
||||
// 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;
|
||||
// return false;
|
||||
// };
|
||||
//
|
||||
// anim.onFrame = [&](){
|
||||
// anim.apply(*boss.sprite);
|
||||
// };
|
||||
//
|
||||
// while(anim.playing) {
|
||||
// anim.update();
|
||||
// FAKE_RENDER();
|
||||
// }
|
||||
//
|
||||
// REQUIRE(loop_ran == true);
|
||||
// REQUIRE(anim.playing == false);
|
||||
// }
|
||||
//
|
||||
// TEST_CASE("confirm transition changes work", "[animation-new]") {
|
||||
// textures::init();
|
||||
// sound::init();
|
||||
// sound::mute(true);
|
||||
//
|
||||
// auto sprite = *textures::get_sprite("rat_king_boss").sprite;
|
||||
// sf::Vector2f pos{100,100};
|
||||
// sprite.setPosition(pos);
|
||||
// auto scale = sprite.getScale();
|
||||
// auto anim = load_animation("rat_king_boss");
|
||||
//
|
||||
// // also testing that onFrame being null means it's not run
|
||||
// REQUIRE(anim.onFrame == nullptr);
|
||||
//
|
||||
// anim.play();
|
||||
// REQUIRE(anim.playing == true);
|
||||
//
|
||||
// while(anim.playing) {
|
||||
// anim.update();
|
||||
// anim.motion(sprite, pos, scale);
|
||||
// FAKE_RENDER();
|
||||
// }
|
||||
//
|
||||
// REQUIRE(anim.playing == false);
|
||||
// REQUIRE(pos == sf::Vector2f{100, 100});
|
||||
// REQUIRE(scale != sf::Vector2f{0,0});
|
||||
// }
|
||||
|
||||
TEST_CASE("playing with delta time", "[animation-new]") {
|
||||
animation::Timer timer;
|
||||
timer.start();
|
||||
|
||||
for(int i = 0; i < 20; i++) {
|
||||
FAKE_RENDER();
|
||||
auto [tick_count, alpha] = timer.commit();
|
||||
// fmt::println("tick: {}, alpha: {}", tick_count, alpha);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue