Skip to content

Commit

Permalink
Move into submodule and add method to add to top level namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
kfischer-okarin committed Jan 10, 2023
1 parent f3e2cd7 commit 1c736a9
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 200 deletions.
1 change: 1 addition & 0 deletions app/main.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'lib/dragon_skeleton.rb'
require 'lib/dragon_skeleton/animations.rb'
require 'lib/dragon_skeleton/animations/asesprite_json.rb'
require 'lib/dragon_skeleton/animated_sprite.rb'
Expand Down
10 changes: 10 additions & 0 deletions lib/dragon_skeleton.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module DragonSkeleton
class << self
def add_to_top_level_namespace(*modules)
modules = modules.empty? ? constants : modules
modules.each do |module_name|
Object.const_set module_name, const_get(module_name)
end
end
end
end
36 changes: 19 additions & 17 deletions lib/dragon_skeleton/animated_sprite.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
module AnimatedSprite
class << self
def build(animations:, **base)
base.to_sprite(
animations: animations,
animation: nil
)
end

def perform_tick(animated_sprite, animation:)
if animation == animated_sprite[:animation]
Animations.perform_tick animated_sprite[:animation_state]
else
animated_sprite[:animation_state] = Animations.start!(
animated_sprite,
animation: animated_sprite[:animations][animation]
module DragonSkeleton
module AnimatedSprite
class << self
def build(animations:, **base)
base.to_sprite(
animations: animations,
animation: nil
)
animated_sprite[:animation] = animation
end

def perform_tick(animated_sprite, animation:)
if animation == animated_sprite[:animation]
Animations.perform_tick animated_sprite[:animation_state]
else
animated_sprite[:animation_state] = Animations.start!(
animated_sprite,
animation: animated_sprite[:animations][animation]
)
animated_sprite[:animation] = animation
end
end
end
end
Expand Down
174 changes: 88 additions & 86 deletions lib/dragon_skeleton/animations.rb
Original file line number Diff line number Diff line change
@@ -1,109 +1,111 @@
module Animations
class << self
def animate(object, to:, duration:)
first_frame_values = {}.tap { |frame|
to.each_key do |key|
frame[key] = object[key]
end
}
animation = build(
frames: [
first_frame_values.merge!(duration: duration, easing: :linear),
to.dup
]
)
start! object, animation: animation, repeat: false
end
module DragonSkeleton
module Animations
class << self
def animate(object, to:, duration:)
first_frame_values = {}.tap { |frame|
to.each_key do |key|
frame[key] = object[key]
end
}
animation = build(
frames: [
first_frame_values.merge!(duration: duration, easing: :linear),
to.dup
]
)
start! object, animation: animation, repeat: false
end

def build(frames:, **base)
{
base: base,
frames: frames.map { |frame|
{
duration: frame[:duration],
metadata: frame[:metadata],
easing: frame[:easing] || :none,
values: frame.except(:duration, :metadata, :easing)
def build(frames:, **base)
{
base: base,
frames: frames.map { |frame|
{
duration: frame[:duration],
metadata: frame[:metadata],
easing: frame[:easing] || :none,
values: frame.except(:duration, :metadata, :easing)
}
}
}
}
end
end

def start!(target, animation:, repeat: true)
{
animation: animation,
target: target,
frame_index: 0,
ticks: 0,
repeat: repeat,
finished: false
}.tap { |animation_state|
target.merge! animation[:base]
apply! target, animation_state: animation_state
}
end
def start!(target, animation:, repeat: true)
{
animation: animation,
target: target,
frame_index: 0,
ticks: 0,
repeat: repeat,
finished: false
}.tap { |animation_state|
target.merge! animation[:base]
apply! target, animation_state: animation_state
}
end

def perform_tick(animation_state)
next_tick animation_state
apply! animation_state[:target], animation_state: animation_state
end
def perform_tick(animation_state)
next_tick animation_state
apply! animation_state[:target], animation_state: animation_state
end

def apply!(target, animation_state:)
target.merge! current_frame_values(animation_state)
end
def apply!(target, animation_state:)
target.merge! current_frame_values(animation_state)
end

def current_frame_metadata(animation_state)
current_frame(animation_state)[:metadata]
end
def current_frame_metadata(animation_state)
current_frame(animation_state)[:metadata]
end

def finished?(animation_state)
animation_state[:finished]
end
def finished?(animation_state)
animation_state[:finished]
end

private
private

def next_tick(animation_state)
return if finished? animation_state
def next_tick(animation_state)
return if finished? animation_state

frames = animation_state[:animation][:frames]
frames = animation_state[:animation][:frames]

animation_state[:ticks] += 1
return unless animation_state[:ticks] >= frames[animation_state[:frame_index]][:duration]
animation_state[:ticks] += 1
return unless animation_state[:ticks] >= frames[animation_state[:frame_index]][:duration]

animation_state[:ticks] = 0
animation_state[:frame_index] = (animation_state[:frame_index] + 1) % frames.length
return unless animation_state[:frame_index] == frames.length - 1 && !animation_state[:repeat]
animation_state[:ticks] = 0
animation_state[:frame_index] = (animation_state[:frame_index] + 1) % frames.length
return unless animation_state[:frame_index] == frames.length - 1 && !animation_state[:repeat]

animation_state[:finished] = true
end
animation_state[:finished] = true
end

def current_frame_values(animation_state)
frame = current_frame(animation_state)
return frame[:values] if frame[:easing] == :none
def current_frame_values(animation_state)
frame = current_frame(animation_state)
return frame[:values] if frame[:easing] == :none

factor = Easing.send(frame[:easing], animation_state[:ticks] / frame[:duration])
next_frame_values = next_frame(animation_state)[:values]
{}.tap { |values|
frame[:values].each do |key, value|
values[key] = ((next_frame_values[key] - value) * factor + value).round
end
}
end
factor = Easing.send(frame[:easing], animation_state[:ticks] / frame[:duration])
next_frame_values = next_frame(animation_state)[:values]
{}.tap { |values|
frame[:values].each do |key, value|
values[key] = ((next_frame_values[key] - value) * factor + value).round
end
}
end

def current_frame(animation_state)
animation_state[:animation][:frames][animation_state[:frame_index]]
end
def current_frame(animation_state)
animation_state[:animation][:frames][animation_state[:frame_index]]
end

def next_frame(animation_state)
frames = animation_state[:animation][:frames]
frames[(animation_state[:frame_index] + 1) % frames.length]
def next_frame(animation_state)
frames = animation_state[:animation][:frames]
frames[(animation_state[:frame_index] + 1) % frames.length]
end
end
end

module Easing
class << self
def linear(t)
t
module Easing
class << self
def linear(t)
t
end
end
end
end
Expand Down
Loading

0 comments on commit 1c736a9

Please sign in to comment.