#pragma once #include #include #include #include #include #include #include #include #include #include "ease2.hpp" #include #include "json_mods.hpp" namespace animate2 { template struct NameOf; struct Sheet { int frames{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{}; std::pair commit(); void start(); void reset(); void restart(); sf::Time getElapsedTime(); }; struct Sequence { std::vector frames{}; std::vector durations{}; size_t current{0}; int loop_count{0}; size_t frame_count{0}; 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 flipped{false}; float ease_rate{0.5f}; bool scaled{false}; // handled by onLoop bool toggled{false}; bool looped{false}; std::string easing{"in_out_back"}; std::string motion{"move_rush"}; // change to using a callback function for these ease2::EaseFunc easing_func{ease2::get_easing(easing)}; ease2::MotionFunc motion_func{ease2::get_motion(motion)}; std::shared_ptr shader{nullptr}; 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; using OnFrameHandler = std::function; inline bool DefaultOnLoop(Sequence& seq, Transform& tr) { if(tr.toggled) { seq.current = seq.frame_count - 1; } else { seq.current = 0; } return tr.looped; } using Form = std::pair; using Sound = std::pair; class Animate2 { public: Sheet sheet; std::unordered_map sequences; std::unordered_map transforms; std::unordered_map forms; std::unordered_map> sounds; OnFrameHandler onFrame = nullptr; Sequence sequence{}; Transform transform{}; std::vector $frame_rects{calc_frames()}; OnLoopHandler onLoop = DefaultOnLoop; bool playing = false; // mostly for debugging purposes std::string form_name="idle"; std::string sequence_name=""; std::string transform_name=""; std::vector calc_frames(); void play(); void play_sound(); void stop(); bool has_form(const std::string& as_form); void set_form(const std::string& form); void apply(sf::Sprite& sprite); void apply(sf::View& view_out, sf::Vector2f pos, sf::Vector2f size); void apply_effect(std::shared_ptr effect); void update(); void motion(sf::Sprite& sprite, sf::Vector2f pos, sf::Vector2f scale); std::pair commit(); }; Animate2 load(const std::string &file, const std::string &anim_name); ENROLL_COMPONENT(Sheet, frames, frame_width, frame_height); ENROLL_COMPONENT(Sequence, frames, durations); ENROLL_COMPONENT(Transform, min_x, min_y, max_x, max_y, flipped, ease_rate, scaled, toggled, looped, easing, motion); ENROLL_COMPONENT(Animate2, sheet, sequences, transforms, forms, sounds); }