raycaster/animate2.hpp

101 lines
2.5 KiB
C++

#pragma once
#include <memory>
#include <chrono>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/System/Time.hpp>
#include <functional>
#include "ease2.hpp"
#include <fmt/core.h>
namespace animate2 {
struct Sheet {
int width{0};
int height{0};
int frame_width{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 {
std::vector<int> frames{};
std::vector<std::chrono::milliseconds> durations{};
size_t current{0};
int loop_count{0};
size_t frame_count{frames.size()};
Timer timer{};
float subframe{0.0f};
};
struct Transform {
// how to know when a transform ends?
float min_x{1.0f};
float min_y{1.0f};
float max_x{1.0f};
float max_y{1.0f};
bool simple{true};
bool flipped{false};
float ease_rate{0.5f};
float speed{0.1f};
bool scaled{false};
bool stationary{false};
// these can handled by the onLoop, same as ganim8 does it
bool toggled{false};
bool looped{false};
std::shared_ptr<sf::Shader> shader{nullptr};
// change to using a callback function for these
ease2::EaseFunc easing = ease2::in_out_back;
ease2::MoveFunc motion = ease2::move_rush;
float twitching(Sequence& seq);
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. */
using OnLoopHandler = std::function<bool(Sequence& seq, Transform& tr)>;
using OnFrameHandler = std::function<void()>;
inline bool DefaultOnLoop(Sequence& seq, Transform& tr) {
seq.current = 0;
return tr.looped;
}
class Animate2 {
public:
Sheet $sheet;
Sequence $sequence;
Transform $transform;
OnFrameHandler onFrame = nullptr;
std::vector<sf::IntRect> $frame_rects{calc_frames()};
OnLoopHandler onLoop = DefaultOnLoop;
bool playing = false;
std::vector<sf::IntRect> calc_frames();
void play();
void stop();
void apply(sf::Sprite& sprite);
void update_frame();
void update();
void motion(sf::Vector2f& pos_out, sf::Vector2f& scale_out);
};
}