module DragonSkeleton::Animations
Provides a simple functional style animation system.
In the simplest case, a frame is a hash of values to be set on the target and a duration:
animation = Animations.build( frames: [ { tile_x: 0, tile_y: 0, duration: 5 }, { tile_x: 32, tile_y: 0, duration: 5 } ] )
It can then be started via ::start!
on a target (e.g. a sprite):
sprite = { x: 100, y: 100, w: 32, h: 32, tile_w: 32, tile_h: 32, path: 'resources/character.png' } animation_state = Animations.start! sprite, animation: animation
and every tick you need to call ::perform_tick
to advance the animation:
Animations.perform_tick animation_state
By default the animation will stay on a frame until the duration is reached, then immediately move to the next frame but you can also specify an easing function to gradually interpolate between frames:
animation = Animations.build( frames: [ { x: 0, y: 0, duration: 5, easing: :linear }, { x: 100, tile_y: 100, duration: 5, easing: :linear } ] )
Constants
- EASING_FUNCTIONS
Easing functions for interpolating between frames.
Following easing functions are provided but you can also add your own to this hash:
- :linear
Public Class Methods
Builds an animation from a list of frames.
Each frame is a hash of values that will be set on the target when the frame becomes active except for the following reserved keys:
- :duration
-
The number of ticks the frame will be active for.
This value is required except for the last frame of a non-repeating animation.
- :metadata
-
A hash of metadata that is available via
::current_frame_metadata
when the frame is active. - :easing
-
The easing function to use when interpolating between the current and next frame.
Check out the
EASING_FUNCTIONS
constant for a list of available easing functions.
# File lib/dragon_skeleton/animations.rb, line 73 def build(frames:) { frames: frames.map { |frame| { duration: frame[:duration], metadata: frame[:metadata], easing: frame[:easing] || :none, values: frame.except(:duration, :metadata, :easing) } } } end
Returns the metadata associated with the active frame of the animation.
# File lib/dragon_skeleton/animations.rb, line 111 def current_frame_metadata(animation_state) current_frame(animation_state)[:metadata] end
Returns true
if the animation has finished.
# File lib/dragon_skeleton/animations.rb, line 116 def finished?(animation_state) animation_state[:finished] end
Creates and starts a one-time animation that will interpolate between the current values of the target and the values in the to
hash.
Returns an animation state that can be passed to ::perform_tick
.
# File lib/dragon_skeleton/animations.rb, line 39 def lerp(target, to:, duration:) first_frame_values = {}.tap { |frame| to.each_key do |key| frame[key] = target[key] end } animation = build( frames: [ first_frame_values.merge!(duration: duration, easing: :linear), to.dup ] ) start! target, animation: animation, repeat: false end
Advances the animation by one tick.
# File lib/dragon_skeleton/animations.rb, line 105 def perform_tick(animation_state) next_tick animation_state update_target animation_state end
Starts an animation on a target and returns an animation state which can be used to advance the animation via ::perform_tick
.
By default the animation will repeat indefinitely but this can be disabled by setting repeat: false
.
# File lib/dragon_skeleton/animations.rb, line 91 def start!(target, animation:, repeat: true) { animation: animation, target: target, frame_index: 0, ticks: 0, repeat: repeat, finished: false }.tap { |animation_state| update_target animation_state } end