Now have a timer for animations that does ticks with deltatime...maybe it works.
This commit is contained in:
parent
c0f69ed026
commit
b7394f832d
5 changed files with 121 additions and 6 deletions
32
animate2.cpp
32
animate2.cpp
|
|
@ -76,6 +76,38 @@ namespace animate2 {
|
||||||
$transform.lerp($sequence, pos, scale);
|
$transform.lerp($sequence, pos, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timer::start() {
|
||||||
|
clock.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::reset() {
|
||||||
|
clock.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::restart() {
|
||||||
|
clock.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Time Timer::getElapsedTime() {
|
||||||
|
return clock.getElapsedTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::begin() {
|
||||||
|
prev_time = clock.getElapsedTime().asSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<int, double> Timer::commit() {
|
||||||
|
current_time = clock.getElapsedTime().asSeconds();
|
||||||
|
frame_duration = current_time - prev_time;
|
||||||
|
accumulator += frame_duration;
|
||||||
|
|
||||||
|
double tick_count = accumulator / DELTA;
|
||||||
|
double alpha = modf(tick_count, &tick_count);
|
||||||
|
accumulator -= tick_count * DELTA;
|
||||||
|
|
||||||
|
return {int(tick_count), alpha};
|
||||||
|
}
|
||||||
|
|
||||||
float Transform::twitching(Sequence& seq) {
|
float Transform::twitching(Sequence& seq) {
|
||||||
float tick = 1 - std::powf(ease_rate, seq.subframe + 0.0001);
|
float tick = 1 - std::powf(ease_rate, seq.subframe + 0.0001);
|
||||||
return easing(tick);
|
return easing(tick);
|
||||||
|
|
|
||||||
20
animate2.hpp
20
animate2.hpp
|
|
@ -7,6 +7,7 @@
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "ease2.hpp"
|
#include "ease2.hpp"
|
||||||
|
#include <fmt/core.h>
|
||||||
|
|
||||||
namespace animate2 {
|
namespace animate2 {
|
||||||
struct Sheet {
|
struct Sheet {
|
||||||
|
|
@ -16,13 +17,30 @@ namespace animate2 {
|
||||||
int frame_height{0};
|
int frame_height{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Timer {
|
||||||
|
double DELTA = 1.0/60.0;
|
||||||
|
double accumulator = 0.0;
|
||||||
|
double prev_time = 0.0;
|
||||||
|
double current_time = 0.0;
|
||||||
|
double frame_duration = 0.0;
|
||||||
|
double alpha = 0.0;
|
||||||
|
sf::Clock clock{};
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
std::pair<int, double> commit();
|
||||||
|
void start();
|
||||||
|
void reset();
|
||||||
|
void restart();
|
||||||
|
sf::Time getElapsedTime();
|
||||||
|
};
|
||||||
|
|
||||||
struct Sequence {
|
struct Sequence {
|
||||||
std::vector<int> 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};
|
||||||
size_t frame_count{frames.size()};
|
size_t frame_count{frames.size()};
|
||||||
sf::Clock timer{};
|
Timer timer{};
|
||||||
float subframe{0.0f};
|
float subframe{0.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#ifndef FSM_DEBUG
|
#ifndef FSM_DEBUG
|
||||||
#define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break
|
#define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break
|
||||||
#else
|
#else
|
||||||
int last_event=-1;
|
static int last_event=-1;
|
||||||
#define FSM_STATE(C, S, E, ...) case C::S: if(last_event != int(E)) { last_event = int(E); fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state));}; S(E, ##__VA_ARGS__); break
|
#define FSM_STATE(C, S, E, ...) case C::S: if(last_event != int(E)) { last_event = int(E); fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state));}; S(E, ##__VA_ARGS__); break
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,16 @@ Animate2 crafter() {
|
||||||
return {sheet, sequence, transform};
|
return {sheet, sequence, transform};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FAKE_RENDER() {
|
||||||
|
std::this_thread::sleep_for(Random::milliseconds(5, 32));
|
||||||
|
}
|
||||||
|
|
||||||
void PLAY_TEST(Animate2 &anim) {
|
void PLAY_TEST(Animate2 &anim) {
|
||||||
anim.play();
|
anim.play();
|
||||||
|
|
||||||
while(anim.playing) {
|
while(anim.playing) {
|
||||||
anim.update();
|
anim.update();
|
||||||
std::this_thread::sleep_for(Random::milliseconds(1, 100));
|
FAKE_RENDER();
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE(anim.playing == false);
|
REQUIRE(anim.playing == false);
|
||||||
|
|
@ -114,6 +118,7 @@ TEST_CASE("new animation system", "[animation-new]") {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("confirm frame sequencing works", "[animation-new]") {
|
TEST_CASE("confirm frame sequencing works", "[animation-new]") {
|
||||||
textures::init();
|
textures::init();
|
||||||
animation::init();
|
animation::init();
|
||||||
|
|
@ -165,15 +170,37 @@ TEST_CASE("confirm transition changes work", "[animation-new]") {
|
||||||
|
|
||||||
anim.play();
|
anim.play();
|
||||||
|
|
||||||
|
sf::Clock clock;
|
||||||
|
clock.start();
|
||||||
|
sf::Time start;
|
||||||
|
sf::Time delta;
|
||||||
|
|
||||||
|
|
||||||
while(anim.playing) {
|
while(anim.playing) {
|
||||||
|
start = clock.getElapsedTime();
|
||||||
|
|
||||||
anim.update();
|
anim.update();
|
||||||
anim.motion(pos, scale);
|
anim.motion(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);
|
||||||
|
|
||||||
|
delta = clock.getElapsedTime() - start;
|
||||||
|
fmt::println("FRAME RATE {}", 1.0f / delta.asSeconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE(anim.playing == false);
|
REQUIRE(anim.playing == false);
|
||||||
REQUIRE(pos != sf::Vector2f{0,0});
|
REQUIRE(pos != sf::Vector2f{0,0});
|
||||||
REQUIRE(scale != sf::Vector2f{0,0});
|
REQUIRE(scale != sf::Vector2f{0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("playing with delta time", "[animation-new]") {
|
||||||
|
animate2::Timer timer;
|
||||||
|
|
||||||
|
for(int i = 0; i < 20; i++) {
|
||||||
|
timer.begin();
|
||||||
|
FAKE_RENDER();
|
||||||
|
auto [tick_count, alpha] = timer.commit();
|
||||||
|
fmt::println("tick: {}, alpha: {}", tick_count, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#define FSM_DEBUG 1
|
||||||
#include "sound.hpp"
|
#include "sound.hpp"
|
||||||
#include "ai.hpp"
|
#include "ai.hpp"
|
||||||
#include "animation.hpp"
|
#include "animation.hpp"
|
||||||
|
|
@ -11,6 +12,9 @@
|
||||||
#include <guecs/ui.hpp>
|
#include <guecs/ui.hpp>
|
||||||
#include "gui/event_router.hpp"
|
#include "gui/event_router.hpp"
|
||||||
#include "gui/guecstra.hpp"
|
#include "gui/guecstra.hpp"
|
||||||
|
#include "animate2.hpp"
|
||||||
|
|
||||||
|
bool YES_SYNC=true;
|
||||||
|
|
||||||
namespace animator {
|
namespace animator {
|
||||||
struct UI {
|
struct UI {
|
||||||
|
|
@ -53,6 +57,7 @@ namespace animator {
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
START=__LINE__,
|
START=__LINE__,
|
||||||
|
ANIMATE=__LINE__,
|
||||||
END=__LINE__,
|
END=__LINE__,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -63,21 +68,42 @@ namespace animator {
|
||||||
|
|
||||||
void init(const std::string &sprite_name) {
|
void init(const std::string &sprite_name) {
|
||||||
$ui.init(sprite_name);
|
$ui.init(sprite_name);
|
||||||
|
|
||||||
|
if(YES_SYNC) {
|
||||||
$window.setVerticalSyncEnabled(VSYNC);
|
$window.setVerticalSyncEnabled(VSYNC);
|
||||||
if(FRAME_LIMIT) $window.setFramerateLimit(FRAME_LIMIT);
|
if(FRAME_LIMIT) $window.setFramerateLimit(FRAME_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
$window.setPosition({0,0});
|
$window.setPosition({0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void event(game::Event ev, std::any data={}) {
|
void event(game::Event ev, std::any data={}) {
|
||||||
switch($state) {
|
switch($state) {
|
||||||
FSM_STATE(State, START, ev);
|
FSM_STATE(State, START, ev);
|
||||||
|
FSM_STATE(State, ANIMATE, ev);
|
||||||
FSM_STATE(State, END, ev);
|
FSM_STATE(State, END, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void START(game::Event ev) {
|
void START(game::Event ev) {
|
||||||
|
switch(ev) {
|
||||||
|
case game::Event::TICK:
|
||||||
|
state(State::ANIMATE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
state(State::START);
|
state(State::START);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANIMATE(game::Event ev) {
|
||||||
|
switch(ev) {
|
||||||
|
case game::Event::TICK:
|
||||||
|
// stuff
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state(State::START);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void END(game::Event ev) {
|
void END(game::Event ev) {
|
||||||
}
|
}
|
||||||
|
|
@ -132,8 +158,20 @@ int main(int argc, char* argv[]) {
|
||||||
animator::FSM main;
|
animator::FSM main;
|
||||||
main.init(argv[1]);
|
main.init(argv[1]);
|
||||||
|
|
||||||
|
animate2::Timer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
while(main.active()) {
|
while(main.active()) {
|
||||||
|
timer.begin();
|
||||||
main.render();
|
main.render();
|
||||||
|
auto [ticks, alpha] = timer.commit();
|
||||||
|
fmt::println("TICK: {}, alpha: {}", ticks, alpha);
|
||||||
|
|
||||||
|
for(int i = 0; i < ticks; i++) {
|
||||||
|
main.event(game::Event::TICK, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// do something with alpha....
|
||||||
main.handle_keyboard_mouse();
|
main.handle_keyboard_mouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue