164 lines
5.5 KiB
C++
164 lines
5.5 KiB
C++
/* +=======================================================+
|
|
____/ \____ /: Open source game framework licensed to freely use, :
|
|
\ / / : copy, and modify - created for dank.game :
|
|
+==\ ^__^ /==+ : :
|
|
: ~/ \~ : : Download at https://open.shampoo.ooo/shampoo/spacebox :
|
|
: ~~~~~~~~~~~~ : +=======================================================+
|
|
: SPACE ~~~~~ : /
|
|
: ~~~~~~~ BOX :/
|
|
+=============*/
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
#include "glm/common.hpp"
|
|
#include "Timer.hpp"
|
|
|
|
namespace sb
|
|
{
|
|
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);
|
|
|
|
};
|
|
|
|
namespace animation
|
|
{
|
|
template<typename Edge>
|
|
class LERP
|
|
{
|
|
enum Playback { _clamp, _repeat, _mirror, _overflow };
|
|
enum Interpolation { _linear, _smooth, _spherical };
|
|
|
|
Timer timer;
|
|
float time = 0.0f;
|
|
float length;
|
|
Edge start;
|
|
Edge end;
|
|
Playback playback = _clamp;
|
|
Interpolation interpolation = _linear;
|
|
|
|
public:
|
|
|
|
LERP(Edge start, Edge end, float length) : start(start), end(end), length(length) {};
|
|
|
|
void clamp();
|
|
|
|
void repeat();
|
|
|
|
void mirror();
|
|
|
|
void overflow();
|
|
|
|
void smooth(bool state);
|
|
|
|
void play();
|
|
|
|
Edge update(float timestamp)
|
|
{
|
|
timer.update(timestamp);
|
|
}
|
|
};
|
|
}
|
|
}
|