Pixel-Composer/scripts/animation_controller/animation_controller.gml
2024-06-08 18:31:27 +07:00

169 lines
No EOL
4.2 KiB
Text

#region global
enum ANIMATOR_END {
loop,
stop
}
#macro ANIMATION_STATIC !(PROJECT.animator.is_playing || PROJECT.animator.frame_progress)
#macro IS_PLAYING PROJECT.animator.is_playing
#macro IS_RENDERING PROJECT.animator.is_rendering
#macro CURRENT_FRAME PROJECT.animator.current_frame
#macro TOTAL_FRAMES PROJECT.animator.frames_total
#macro FRAME_RANGE PROJECT.animator.frame_range
#macro FIRST_FRAME PROJECT.animator.getFirstFrame()
#macro LAST_FRAME PROJECT.animator.getLastFrame()
#macro IS_FIRST_FRAME PROJECT.animator.isFirstFrame()
#macro IS_LAST_FRAME PROJECT.animator.isLastFrame()
#endregion
#region animation class
function AnimationManager() constructor {
frames_total = 30;
current_frame = 0;
real_frame = 0;
time_since_last_frame = 0;
framerate = 30;
is_playing = false;
is_rendering = false;
frame_progress = false;
frame_range = noone;
is_simulating = false;
__debug_animator_counter = 0;
playback = ANIMATOR_END.loop;
static setFrame = function(frame, _round = true) { #region
var _c = current_frame;
frame = clamp(frame, 0, frames_total);
real_frame = frame;
current_frame = _round? round(frame) : frame;
frame_progress = _c != current_frame;
if(frame_progress) {
time_since_last_frame = 0;
RENDER_ALL
}
} #endregion
static getFirstFrame = function(range = true) { INLINE return range && frame_range != noone? frame_range[0] - 1 : 0; }
static getLastFrame = function(range = true) { INLINE return range && frame_range != noone? frame_range[1] - 1 : frames_total - 1; }
static firstFrame = function(range = true) { INLINE setFrame(getFirstFrame(range)); }
static lastFrame = function(range = true) { INLINE setFrame(getLastFrame(range)); }
static isFirstFrame = function() { INLINE return current_frame == getFirstFrame(); }
static isLastFrame = function() { INLINE return current_frame == getLastFrame(); }
static resetAnimation = function() { #region
INLINE
array_foreach(PROJECT.allNodes, function(node) { node.resetAnimation(); });
} #endregion
static toggle = function() { #region
INLINE
is_playing = !is_playing;
frame_progress = true;
time_since_last_frame = 0;
} #endregion
static pause = function() { #region
INLINE
is_playing = false;
frame_progress = true;
time_since_last_frame = 0;
} #endregion
static play = function() { #region
INLINE
if(is_simulating) setFrame(0);
else firstFrame();
is_playing = true;
frame_progress = true;
time_since_last_frame = 0;
} #endregion
static render = function() { #region
INLINE
if(is_simulating) setFrame(0);
else firstFrame();
is_playing = true;
is_rendering = true;
frame_progress = true;
time_since_last_frame = 0;
} #endregion
static resume = function() { #region
INLINE
is_playing = true;
frame_progress = true;
time_since_last_frame = 0;
} #endregion
static stop = function() { #region
INLINE
firstFrame();
is_playing = false;
time_since_last_frame = 0;
} #endregion
static step = function() { #region
INLINE
if(frame_range != noone) {
var _fr0 = min(frame_range[0], frame_range[1]);
var _fr1 = max(frame_range[0], frame_range[1]);
if(_fr0 == _fr1) {
frame_range = noone;
} else {
frame_range[0] = max(_fr0, 0);
frame_range[1] = min(_fr1, frames_total);
}
}
if(!is_playing) return;
var _frTime = 1 / framerate;
time_since_last_frame += delta_time / 1_000_000;
var tslf = time_since_last_frame;
if(0 && IS_CMD) {
setFrame(real_frame + 1);
} else if(time_since_last_frame >= _frTime) {
var dt = time_since_last_frame - _frTime;
setFrame(real_frame + 1);
time_since_last_frame = dt;
var _maxFrame = frame_range != noone? frame_range[1] : frames_total;
if(current_frame >= _maxFrame) {
firstFrame();
if(playback == ANIMATOR_END.stop || is_rendering) {
is_playing = false;
is_rendering = false;
time_since_last_frame = 0;
}
}
}
} #endregion
}
#endregion