Skip to content

Instantly share code, notes, and snippets.

@rutan
Created Jul 11, 2015
Embed
What would you like to do?
# encoding: utf-8
#===============================================================================
# ■ Tweenアニメーション for RGSS3
#-------------------------------------------------------------------------------
# Ru/むっくRu
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# 【更新履歴】
#===============================================================================
module Torigoya
class Tween
def initialize(target, options = {})
@target = target
@loop = !!options[:loop]
@paused = !!options[:paused]
@actions = []
Tween.push(self)
end
attr_reader :target
def to(propaties = {}, duration = 60, ease = :linear)
@actions.push([:to, {
propaties: propaties,
duration: duration,
ease: ease,
}])
self
end
def set(propaties = {}, target = nil)
@actions.push([:set, {
target: target || @target,
propaties: propaties,
}])
self
end
def wait(duration = 60)
@actions.push([:wait, {
duration: duration,
}])
self
end
def call(method = nil, &block)
@actions.push([:call, {
method: method,
block: block,
}])
self
end
def play(tween)
@actions.push([:play, {
tween: tween,
}])
self
end
def start
@paused = false
end
def pause
@paused = true
end
def step
return false if @target.respond_to?(:disposed?) && @target.disposed?
return true if @paused
step_fiber.resume
rescue RGSSError => e # 対象が解放済み時に発生する例外
false
end
def step_fiber
@step_fiber ||= Fiber.new do
i = 0
loop do
name, action = @actions[i]
case name
when :to
propaties = action[:propaties]
duration = action[:duration]
ease =
case action[:ease]
when Symbol
Easing.method(action[:ease])
when Proc
action[:ease]
end
original_propaties = {}
propaties.keys.each { |key| original_propaties[key] = @target.public_send(key) }
duration.times do |i|
original_propaties.each do |key, original|
n = ease.call(i + 1, original, propaties[key] - original, duration)
@target.public_send(:"#{key}=", n)
end
Fiber.yield(true)
end
when :set
target = action[:target]
propaties = action[:propaties]
propaties.each do |key, value|
target.public_send(:"#{key}=", value)
end
when :wait
action[:duration].times { Fiber.yield(true) }
when :call
method = action[:method]
block = action[:block]
if block
case method
when nil; block.call(self)
when Symbol; @target.public_send(method, &block)
when Proc; method.call(&block)
end
else
case method
when Symbol; @target.public_send(method)
when Proc; method.call
end
end
when :play
action[:tween].start
end
i += 1
unless i < @actions.size
if @loop
i = 0
else
break
end
end
end
loop { Fiber.yield(false) }
end
end
def self.get(target, options = {})
self.new(target, options)
end
def self.step
@list ||= []
@list.select! { |tween| tween.step }
end
def self.push(tween)
@list ||= []
@list.push tween
end
module Easing
# Linear
def self.linear(time, begin_value, change_value, duration)
begin_value + change_value * time / duration
end
# Easing In Quad
def self.ease_in_quad(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * time * time
end
# Easing Out Quad
def self.ease_out_quad(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value - change_value * time * (time - 2)
end
# Easing In/Out Quad
def self.ease_in_out_quad(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if time < 1
begin_value + change_value * time * time
else
time -= 1
begin_value - change_value * (time * (time - 2) - 1)
end
end
# Easing In Cubic
def self.ease_in_cubic(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (time ** 3)
end
# Easing Out Cubic
def self.ease_out_cubic(time, begin_value, change_value, duration)
time /= duration.to_f
time -= 1
begin_value + change_value * (time ** 3 + 1)
end
# Easing In/Out Cubic
def self.ease_in_out_cubic(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if time < 1
begin_value + change_value * (time ** 3)
else
time -= 2
begin_value + change_value * (time ** 3 + 2)
end
end
# Easing In Quartic
def self.ease_in_quart(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (time ** 4)
end
# Easing Out Quartic
def self.ease_out_quart(time, begin_value, change_value, duration)
time /= duration.to_f
time -= 1
begin_value - change_value * (time ** 4 - 1)
end
# Easing In/Out Quartic
def self.ease_in_out_quart(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if time < 1
begin_value + change_value * (time ** 4)
else
time -= 2
begin_value - change_value * (time ** 4 - 2)
end
end
# Easing In Quintic
def self.ease_in_quint(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (time ** 5)
end
# Easing Out Quintic
def self.ease_out_quint(time, begin_value, change_value, duration)
time /= duration.to_f
time -= 1
begin_value + change_value * (time ** 5 + 1)
end
# Easing In/Out Quintic
def self.ease_in_out_quint(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if time < 1
begin_value + change_value * (time ** 5)
else
time -= 2
begin_value + change_value * (time ** 5 + 2)
end
end
# Easing In Sine
def self.ease_in_sine(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (1 - Math.cos(time * (Math::PI / 2)))
end
# Easing Out Sine
def self.ease_out_sine(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * Math.sin(time * (Math::PI / 2))
end
# Easing In/Out Sine
def self.ease_in_out_sine(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value - change_value / 2 * (Math.cos(Math::PI * time) - 1)
end
# Easing In Exponential
def self.ease_in_expo(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (2 ** (10 * (time - 1)))
end
# Easing Out Exponential
def self.ease_out_expo(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value + change_value * (1 - (2 ** (-10 * time)))
end
# Easing In/Out Exponential
def self.ease_in_out_expo(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if time < 1
begin_value + change_value * (2 ** (10 * (time - 1)))
else
begin_value + change_value * (-2 ** (-10 * (time - 1)) + 2)
end
end
# Easing In Circular
def self.ease_in_circ(time, begin_value, change_value, duration)
time /= duration.to_f
begin_value - change_value * (Math.sqrt(1 - time * time) - 1)
end
# Easing Out Circular
def self.ease_out_circ(time, begin_value, change_value, duration)
time /= duration.to_f
time -= 1
begin_value + change_value * Math.sqrt(1 - time * time)
end
# Easing In/Out Circular
def self.ease_in_out_circ(time, begin_value, change_value, duration)
time /= duration.to_f / 2
change_value /= 2
if (time < 1)
begin_value - change_value * (Math.sqrt(1 - time * time) - 1)
else
time -= 2
begin_value + change_value * (Math.sqrt(1 + time * time) + 1)
end
end
end
end
end
class << Graphics
alias torigoya_tween_update update
def update
Torigoya::Tween.step
torigoya_tween_update
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment