mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
251 lines
8.5 KiB
Ruby
251 lines
8.5 KiB
Ruby
#===============================================================================
|
|
# Methods used by both AnimationPlayer and AnimationEditor::Canvas.
|
|
#===============================================================================
|
|
module AnimationPlayer::Helper
|
|
PROPERTIES_SET_BY_SPAWNER = {
|
|
:random_direction => [:x, :y],
|
|
:random_direction_gravity => [:x, :y]
|
|
}
|
|
GRAVITY_STRENGTH = 300
|
|
BATTLE_MESSAGE_BAR_HEIGHT = 96 # NOTE: You shouldn't need to change this.
|
|
|
|
module_function
|
|
|
|
# Returns the duration of the animation in frames (1/20ths of a second).
|
|
def get_duration(particles)
|
|
ret = 0
|
|
particles.each do |particle|
|
|
particle.each_pair do |property, value|
|
|
next if !value.is_a?(Array) || value.empty?
|
|
max = value.last[0] + value.last[1] # Keyframe + duration
|
|
ret = max if ret < max
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Returns the frame that the particle has its earliest command.
|
|
def get_first_command_frame(particle)
|
|
ret = -1
|
|
particle.each_pair do |property, cmds|
|
|
next if !cmds.is_a?(Array) || cmds.empty?
|
|
cmds.each do |cmd|
|
|
ret = cmd[0] if ret < 0 || ret > cmd[0]
|
|
end
|
|
end
|
|
return (ret >= 0) ? ret : 0
|
|
end
|
|
|
|
# Returns the frame that the particle has (the end of) its latest command.
|
|
def get_last_command_frame(particle)
|
|
ret = -1
|
|
particle.each_pair do |property, cmds|
|
|
next if !cmds.is_a?(Array) || cmds.empty?
|
|
cmds.each do |cmd|
|
|
ret = cmd[0] + cmd[1] if ret < cmd[0] + cmd[1]
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# For spawner particles
|
|
def get_particle_delay(particle, instance)
|
|
case particle[:spawner] || :none
|
|
when :random_direction, :random_direction_gravity
|
|
return instance / 4
|
|
end
|
|
return 0
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def get_xy_focus(particle, user_index, target_index, user_coords, target_coords)
|
|
ret = nil
|
|
case particle[:focus]
|
|
when :foreground, :midground, :background
|
|
when :user
|
|
ret = [user_coords.clone]
|
|
when :target
|
|
ret = [target_coords.clone]
|
|
when :user_and_target
|
|
ret = [user_coords.clone, target_coords.clone]
|
|
when :user_side_foreground, :user_side_background
|
|
ret = [Battle::Scene.pbBattlerPosition(user_index)]
|
|
when :target_side_foreground, :target_side_background
|
|
ret = [Battle::Scene.pbBattlerPosition(target_idx)]
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def get_xy_offset(particle, sprite)
|
|
ret = [0, 0]
|
|
case particle[:graphic]
|
|
when "USER", "USER_OPP", "USER_FRONT", "USER_BACK",
|
|
"TARGET", "TARGET_OPP", "TARGET_FRONT", "TARGET_BACK"
|
|
ret[1] += sprite.bitmap.height / 2 if sprite
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# property is :x or :y.
|
|
def apply_xy_focus_to_sprite(sprite, property, value, focus)
|
|
result = value
|
|
coord_idx = (property == :x) ? 0 : 1
|
|
if focus
|
|
if focus.length == 2
|
|
distance = GameData::Animation::USER_AND_TARGET_SEPARATION
|
|
result = focus[0][coord_idx] + ((value.to_f / distance[coord_idx]) * (focus[1][coord_idx] - focus[0][coord_idx])).to_i
|
|
else
|
|
result = value + focus[0][coord_idx]
|
|
end
|
|
end
|
|
case property
|
|
when :x then sprite.x = result
|
|
when :y then sprite.y = result
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Returns either a number or an array of two numbers.
|
|
def get_z_focus(particle, user_index, target_index)
|
|
ret = 0
|
|
case particle[:focus]
|
|
when :foreground
|
|
ret = 2000
|
|
when :midground
|
|
ret = 1000
|
|
when :background
|
|
# NOTE: No change.
|
|
when :user
|
|
ret = 1000 + ((100 * ((user_index / 2) + 1)) * (user_index.even? ? 1 : -1))
|
|
when :target
|
|
ret = 1000 + ((100 * ((target_index / 2) + 1)) * (target_index.even? ? 1 : -1))
|
|
when :user_and_target
|
|
user_pos = 1000 + ((100 * ((user_index / 2) + 1)) * (user_index.even? ? 1 : -1))
|
|
target_pos = 1000 + ((100 * ((target_index / 2) + 1)) * (target_index.even? ? 1 : -1))
|
|
ret = [user_pos, target_pos]
|
|
when :user_side_foreground, :target_side_foreground
|
|
this_idx = (particle[:focus] == :user_side_foreground) ? user_index : target_index
|
|
ret = 1000
|
|
ret += 1000 if this_idx.even? # On player's side
|
|
when :user_side_background, :target_side_background
|
|
this_idx = (particle[:focus] == :user_side_background) ? user_index : target_index
|
|
ret = 1000 if this_idx.even? # On player's side
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def apply_z_focus_to_sprite(sprite, z, focus)
|
|
if focus.is_a?(Array)
|
|
distance = GameData::Animation::USER_AND_TARGET_SEPARATION[2]
|
|
if z >= 0
|
|
if focus[0] > focus[1]
|
|
sprite.z = focus[0] + z
|
|
else
|
|
sprite.z = focus[0] - z
|
|
end
|
|
elsif z <= distance
|
|
if focus[0] > focus[1]
|
|
sprite.z = focus[1] + z + distance
|
|
else
|
|
sprite.z = focus[1] - z + distance
|
|
end
|
|
else
|
|
sprite.z = focus[0] + ((z.to_f / distance) * (focus[1] - focus[0])).to_i
|
|
end
|
|
elsif focus
|
|
sprite.z = z + focus
|
|
else
|
|
sprite.z = z
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# user_sprites, target_sprites = [front sprite, back sprite]
|
|
def set_bitmap_and_origin(particle, sprite, user_index, target_index, user_sprites, target_sprites)
|
|
return if sprite&.is_a?(Battle::Scene::BattlerSprite)
|
|
case particle[:graphic]
|
|
when "USER", "USER_OPP", "USER_FRONT", "USER_BACK",
|
|
"TARGET", "TARGET_OPP", "TARGET_FRONT", "TARGET_BACK"
|
|
filename = nil
|
|
case particle[:graphic]
|
|
when "USER"
|
|
filename = (user_index.even?) ? user_sprites[1] : user_sprites[0]
|
|
when "USER_OPP"
|
|
filename = (user_index.even?) ? user_sprites[0] : user_sprites[1]
|
|
when "USER_FRONT"
|
|
filename = user_sprites[0]
|
|
when "USER_BACK"
|
|
filename = user_sprites[1]
|
|
when "TARGET"
|
|
filename = (target_index.even?) ? target_sprites[1] : target_sprites[0]
|
|
when "TARGET_OPP"
|
|
filename = (target_index.even?) ? target_sprites[0] : target_sprites[1]
|
|
when "TARGET_FRONT"
|
|
filename = target_sprites[0]
|
|
when "TARGET_BACK"
|
|
filename = target_sprites[1]
|
|
end
|
|
sprite.bitmap = RPG::Cache.load_bitmap("", filename)
|
|
sprite.ox = sprite.bitmap.width / 2
|
|
sprite.oy = sprite.bitmap.height
|
|
else
|
|
sprite.bitmap = RPG::Cache.load_bitmap("Graphics/Battle animations/", particle[:graphic])
|
|
sprite.src_rect.set(0, 0, sprite.bitmap.width, sprite.bitmap.height)
|
|
if [:foreground, :midground, :background].include?(particle[:focus]) &&
|
|
sprite.bitmap.width >= Settings::SCREEN_WIDTH &&
|
|
sprite.bitmap.height >= Settings::SCREEN_HEIGHT - BATTLE_MESSAGE_BAR_HEIGHT
|
|
sprite.ox = 0
|
|
sprite.oy = 0
|
|
elsif sprite.bitmap.width > sprite.bitmap.height * 2
|
|
sprite.src_rect.set(0, 0, sprite.bitmap.height, sprite.bitmap.height)
|
|
sprite.ox = sprite.bitmap.height / 2
|
|
sprite.oy = sprite.bitmap.height / 2
|
|
else
|
|
sprite.ox = sprite.bitmap.width / 2
|
|
sprite.oy = sprite.bitmap.height / 2
|
|
end
|
|
if particle[:graphic][/\[\s*bottom\s*\]\s*$/i] # [bottom] at end of filename
|
|
sprite.oy = sprite.bitmap.height
|
|
end
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def interpolate(interpolation, start_val, end_val, duration, start_time, now)
|
|
case interpolation
|
|
when :linear
|
|
return lerp(start_val, end_val, duration, start_time, now).to_i
|
|
when :ease_in # Quadratic
|
|
ret = start_val
|
|
x = (now - start_time) / duration.to_f
|
|
ret += (end_val - start_val) * x * x
|
|
return ret.round
|
|
when :ease_out # Quadratic
|
|
ret = start_val
|
|
x = (now - start_time) / duration.to_f
|
|
ret += (end_val - start_val) * (1 - ((1 - x) * (1 - x)))
|
|
return ret.round
|
|
when :ease_both # Quadratic
|
|
ret = start_val
|
|
x = (now - start_time) / duration.to_f
|
|
if x < 0.5
|
|
ret += (end_val - start_val) * x * x * 2
|
|
else
|
|
ret += (end_val - start_val) * (1 - (((-2 * x) + 2) * ((-2 * x) + 2) / 2))
|
|
end
|
|
return ret.round
|
|
when :gravity # Used by particle spawner
|
|
# end_val is [initial speed, gravity]
|
|
# s = ut + 1/2 at^2
|
|
t = now - start_time
|
|
ret = start_val + (end_val[0] * t) + (end_val[1] * t * t / 2)
|
|
return ret.round
|
|
end
|
|
raise _INTL("Unknown interpolation method {1}.", interpolation)
|
|
end
|
|
end
|