122 lines
4.5 KiB
C++
122 lines
4.5 KiB
C++
/* ✨ +------------------------------------------------------+
|
|
____/ \____ ✨/| 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 <vector>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
#include "Timer.hpp"
|
|
|
|
class Animation
|
|
{
|
|
|
|
private:
|
|
|
|
typedef std::function<void()> 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;
|
|
}
|