I could have posted this in the snippet area, as it's more of a Script for scripters...:p
but would probably get more attention here.
Provides a set of functions to change a value to another with specific curves.
It can be used for a lot of different things, like generating curves values for
statistics, or to create nice movements.
each method takes 3 Values,
start and end value, and finally factor.
Factor is a float, between 0 and 1, representing how far between start and end.
Each of this methods affect how factor evolve over time , and therefore how
fast or slow it goes.
You can check this : http://codeplea.com/simple-interpolation for more info.
Both of the following Script are compatible with XP and VX
Main Script
[rgss]#===============================================================================
<span style="color:#000080; font-style:italic;">=begin
<span style="color:#000080; font-style:italic;">Interpolation Module
<span style="color:#000080; font-style:italic;">Trebor777
<span style="color:#000080; font-style:italic;">v1.0 # 23/09/2010
<span style="color:#000080; font-style:italic;">--------------------------------------------------------------------------------
<span style="color:#000080; font-style:italic;">Provides a set of functions to change a value to another with specific curves.
<span style="color:#000080; font-style:italic;">can be used for a lot of different things, like generating curves values for
<span style="color:#000080; font-style:italic;">statistics, or to create nice movements.
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;">each method takes 3 Values,
<span style="color:#000080; font-style:italic;">start and end value, and finally factor.
<span style="color:#000080; font-style:italic;">Factor is a float, between 0 and 1, representing how far between start and end.
<span style="color:#000080; font-style:italic;">Each of this methods affect how factor evolve over time , and therefore how
<span style="color:#000080; font-style:italic;"> fast or slow it goes.
<span style="color:#000080; font-style:italic;">
<span style="color:#000080; font-style:italic;"> You can check this : http://codeplea.com/simple-interpolation for more info.
<span style="color:#000080; font-style:italic;">=end
#===============================================================================
module Interp_Mod
#-----------------------------------------------------------------------------
# Linear Interpolation, by default, acceleration is constant(represented by factor).
def self.lerp(start, end_value, factor)
start + factor * (end_value - start)
end
#-----------------------------------------------------------------------------
# Starts fast, ends slow
def self.decel(start_value, end_value, factor)
lerp(start_value, end_value, (1- (1- factor)**2))
end
#-----------------------------------------------------------------------------
# Starts slow, ends fast
def self.accel(start_value, end_value, factor)
lerp(start_value, end_value, factor**2)
end
#-----------------------------------------------------------------------------
# Smooth start and end
def self.hermite(start, end_value, factor)
lerp(start, end_value, factor**2 * (3.0 - 2.0 * factor))
end
#-----------------------------------------------------------------------------
def self.sinerp(start, end_value, factor)
lerp(start, end_value, Math::sin(factor * Math::PI*0.5))
end
#-----------------------------------------------------------------------------
def self.coserp(start, end_value, factor)
lerp(start, end_value, 1.0-Math::cos(factor * Math::PI*0.5))
end
#-----------------------------------------------------------------------------
# Not restricted by time
def self.lerp_unlim(start, end_value, percentage)
lerp(start, end_value, percentage)
end
end
[/rgss]
Example of use:
[rgss]
class Sprite
#-----------------------------------------------------------------------------
# Move, Setup movement parameters
# move object to the targetted location at x, y, using an interpolation function
# in a specific time frame.
### Parameters ###
# x: int, new location to reach on x-axis
# y: int, new location to reach on y-axis
# time: int, number of frames to move the object.
# OR float, between 0 and 1 if interp_type is :unlim
# interp_type: type of interpolation, default is :decel . type available:
# :accel, :decel, :lerp, :hermite, :cos, :sin, :unlim
#-----------------------------------------------------------------------------
def start_move(x,y, time, interp_type= :decel)
@interp_type = interp_type
@total_time = time.to_f # Convert to float (used later)
@to_x = x # Final location to reach
@to_y = y
@current_iteration = 0 # Frame Counter
@start_smooth = true # Start Execution Boolean
end
#-----------------------------------------------------------------------------
# Update every frame
#-----------------------------------------------------------------------------
unless method_defined? :interpolation_treb777_update # prevent F12 bug
alias :interpolation_treb777_update :update
def update
interpolation_treb777_update
update_move
end
end
#-----------------------------------------------------------------------------
# Update the interpolated movement, depending on the interpolation type
#-----------------------------------------------------------------------------
def update_move
return unless @start_smooth # Exit if Start is false
factor = @current_iteration/@total_time # How much of total time done.
case @interp_type # Select the right methods
when :decel
self.x = Interp_Mod.decel(self.x, @to_x, factor)
self.y = Interp_Mod.decel(self.y, @to_y, factor)
when :accel
self.x = Interp_Mod.accel(self.x, @to_x, factor)
self.y = Interp_Mod.accel(self.y, @to_y, factor)
when :cos
self.x = Interp_Mod.coserp(self.x, @to_x, factor)
self.y = Interp_Mod.coserp(self.y, @to_y, factor)
when :sin
self.x = Interp_Mod.sinerp(self.x, @to_x, factor)
self.y = Interp_Mod.sinerp(self.y, @to_y, factor)
when :lerp
self.x = Interp_Mod.lerp(self.x, @to_x, factor)
self.y = Interp_Mod.lerp(self.y, @to_y, factor)
when :hermite
self.x = Interp_Mod.hermite(self.x, @to_x, factor)
self.y = Interp_Mod.hermite(self.y, @to_y, factor)
when :unlim
self.x = Interp_Mod.lerp_unlim(self.x, @to_x, @total_time)
self.y = Interp_Mod.lerp_unlim(self.y, @to_y, @total_time)
end
@current_iteration += 1 # Increase Iteration
# Check if end is reached
@start_smooth = false if @current_iteration == @total_time
end
end
[/rgss]
Should be compatible without problems.
Here is a Demo Script, that you can put before main, and after those previous 2 script:
[rgss]a = Sprite.new
a.bitmap = Bitmap.new(10,10)
a.bitmap.fill_rect(0,0,10,10, Color.new(255,0,0))
a.x = 10
a.y = 10
a.start_move(100,200,200, :hermite)
loop do
break if Input.trigger?(Input::B)
a.update
Graphics.update
end
[/rgss]