/* ✨ +------------------------------------------------------+ ____/ \____ ✨/| Open source game framework licensed to freely use, | ✨\ / / | copy, and modify. Created for 🌠dank.game🌠 | +--\ . . /--+ | | | ~/ οΈΆ \πŸ‘| | 🌐 https://open.shampoo.ooo/shampoo/spacebox | | ~~~🌊~~~~🌊~ | +------------------------------------------------------+ | SPACE πŸͺπŸ…± OX | / | 🌊 ~ ~~~~ ~~ |/ +-------------*/ #pragma once #include #include #include #include "Timer.hpp" class Animation { private: typedef std::function Callback; bool play_state = false, ending = false, paused = false; float delay = 0.0f, overflow = 0.0f, _frame_length = 0.0f, previous_step_time = 0.0f; sb::Timer timer; Callback step = [](){}; public: Animation(); /*! * @deprecated It is preferable to use Animation::Animation() or Animation::Animation(float) and omit the callback function, * which will eventually be removed from this object. This is because storing the callback function can create copying issues * when std::bind is used to create the callback and the bound object is destroyed before the callback is called. Instead, * check the return value of Animation::update(float) to determine whether or not to call the desired callback externally. * * Create an Animation object by supplying a function and interval at which the function should run. Run Animation::update(float) * regularly with an updated timestamp from Game::update(float), and the function will be launched automatically at the given * interval. If the interval is omitted, the function will run every time Animation::update(float) is run. * * @param step function to be run every given amount of seconds, or zero to run every update * @param frame_length seconds between each run of the function */ Animation(Callback step, float frame_length = 0.0f) : _frame_length(frame_length), step(step) { timer.off(); } /*! * Create an Animation object with a specific amount of time in seconds between each frame. Animation::update(float) will only * return true when it is time to display another frame. * * @param frame_length seconds between each frame */ Animation(float frame_length) : _frame_length(frame_length) { timer.off(); } /*! * Set the duration in seconds of each frame of the animation. * * @param length frame length in seconds */ void frame_length(float length); /*! * Turn the play state to on, causing the animation's callback to run once every frame length. If a delay is given, wait before * running. If the play_once flag is set to true, only play the callback once after the delay. * * @param delay Amount of seconds to delay before running * @param play_once If true, only run the callback once instead of once every frame length */ void play(float delay = 0.0f, bool play_once = false); /*! * Run the animation's callback only once, optionally after a specified delay. If no delay is specified, it will run immediately. * * @param delay Amount of seconds to delay before running */ void play_once(float delay = 0.0f); void pause(); void unpause(); /*! * @param state True to unpause, false to pause */ void toggle(bool state); void reset(); /*! * @param include_delay Specify whether or not to include the delay time in the check * @return True if the animation is playing */ bool playing(bool include_delay = true) const; /*! * Update the timer and check the function's return value to determine whether a new frame of the animation should be produced. * * This will run the callback automatically if it is stored in this object, but the ability to store the callback in this object is * deprecated and will be removed soon. * * @param timestamp Seconds since the program has started, which can be obtained from Game::update(float) * @return True if the next frame of animation should be triggered, false otherwise */ bool update(float timestamp); }; /* Add Animation class to the sb namespace. This should be the default location, but Animation is left in the global namespace * for backward compatibility. */ namespace sb { using ::Animation; }