mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-09 22:24:58 +00:00
More FPS agnosticism, fixed pause after finishing an event's repeating move route
This commit is contained in:
@@ -98,8 +98,6 @@ class Battle::Scene
|
||||
# Update other graphics
|
||||
@sprites["battle_bg"].update if @sprites["battle_bg"].respond_to?("update")
|
||||
Graphics.update
|
||||
@frameCounter += 1
|
||||
@frameCounter = @frameCounter % (Graphics.frame_rate * 12 / 20)
|
||||
end
|
||||
|
||||
def pbInputUpdate
|
||||
@@ -114,9 +112,9 @@ class Battle::Scene
|
||||
cw&.update
|
||||
@battle.battlers.each_with_index do |b, i|
|
||||
next if !b
|
||||
@sprites["dataBox_#{i}"]&.update(@frameCounter)
|
||||
@sprites["pokemon_#{i}"]&.update(@frameCounter)
|
||||
@sprites["shadow_#{i}"]&.update(@frameCounter)
|
||||
@sprites["dataBox_#{i}"]&.update
|
||||
@sprites["pokemon_#{i}"]&.update
|
||||
@sprites["shadow_#{i}"]&.update
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@ class Battle::Scene
|
||||
# Create the battle scene and its elements
|
||||
#=============================================================================
|
||||
def initialize
|
||||
@battle = nil
|
||||
@abortable = false
|
||||
@aborted = false
|
||||
@battleEnd = false
|
||||
@animations = []
|
||||
@frameCounter = 0
|
||||
@battle = nil
|
||||
@abortable = false
|
||||
@aborted = false
|
||||
@battleEnd = false
|
||||
@animations = []
|
||||
end
|
||||
|
||||
# Called whenever the battle begins.
|
||||
|
||||
@@ -225,8 +225,8 @@ class Battle::Scene
|
||||
elsif battler.hp < oldHP
|
||||
pbCommonAnimation("HealthDown", battler) if showAnim && @battle.showAnims
|
||||
end
|
||||
@sprites["dataBox_#{battler.index}"].animateHP(oldHP, battler.hp, battler.totalhp)
|
||||
while @sprites["dataBox_#{battler.index}"].animatingHP
|
||||
@sprites["dataBox_#{battler.index}"].animate_hp(oldHP, battler.hp)
|
||||
while @sprites["dataBox_#{battler.index}"].animating_hp?
|
||||
pbUpdate
|
||||
end
|
||||
end
|
||||
@@ -253,7 +253,7 @@ class Battle::Scene
|
||||
targets.each do |t|
|
||||
anim = Animation::BattlerDamage.new(@sprites, @viewport, t[0].index, t[2])
|
||||
damageAnims.push(anim)
|
||||
@sprites["dataBox_#{t[0].index}"].animateHP(t[1], t[0].hp, t[0].totalhp)
|
||||
@sprites["dataBox_#{t[0].index}"].animate_hp(t[1], t[0].hp)
|
||||
end
|
||||
# Update loop
|
||||
loop do
|
||||
@@ -261,7 +261,7 @@ class Battle::Scene
|
||||
pbUpdate
|
||||
allDone = true
|
||||
targets.each do |t|
|
||||
next if !@sprites["dataBox_#{t[0].index}"].animatingHP
|
||||
next if !@sprites["dataBox_#{t[0].index}"].animating_hp?
|
||||
allDone = false
|
||||
break
|
||||
end
|
||||
@@ -286,8 +286,8 @@ class Battle::Scene
|
||||
endExpLevel = tempExp2 - startExp
|
||||
expRange = endExp - startExp
|
||||
dataBox = @sprites["dataBox_#{battler.index}"]
|
||||
dataBox.animateExp(startExpLevel, endExpLevel, expRange)
|
||||
while dataBox.animatingExp
|
||||
dataBox.animate_exp(startExpLevel, endExpLevel, expRange)
|
||||
while dataBox.animating_exp?
|
||||
pbUpdate
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,14 +4,20 @@
|
||||
class Battle::Scene::PokemonDataBox < Sprite
|
||||
attr_reader :battler
|
||||
attr_accessor :selected
|
||||
attr_reader :animatingHP
|
||||
attr_reader :animatingExp
|
||||
|
||||
# Time in seconds to fully fill the Exp bar (from empty).
|
||||
EXP_BAR_FILL_TIME = 1.75
|
||||
# Time in seconds for this data box to flash when the Exp fully fills.
|
||||
EXP_FULL_FLASH_DURATION = 0.2
|
||||
# Maximum time in seconds to make a change to the HP bar.
|
||||
HP_BAR_CHANGE_TIME = 1.0
|
||||
# Time (in seconds) for one complete sprite bob cycle (up and down) while
|
||||
# choosing a command for this battler or when this battler is being chosen as
|
||||
# a target. Set to nil to prevent bobbing.
|
||||
BOBBING_DURATION = 0.6
|
||||
# Height in pixels of a status icon
|
||||
STATUS_ICON_HEIGHT = 16
|
||||
# Text colors
|
||||
NAME_BASE_COLOR = Color.new(72, 72, 72)
|
||||
NAME_SHADOW_COLOR = Color.new(184, 184, 184)
|
||||
MALE_BASE_COLOR = Color.new(48, 96, 216)
|
||||
@@ -21,18 +27,14 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
|
||||
def initialize(battler, sideSize, viewport = nil)
|
||||
super(viewport)
|
||||
@battler = battler
|
||||
@sprites = {}
|
||||
@spriteX = 0
|
||||
@spriteY = 0
|
||||
@spriteBaseX = 0
|
||||
@selected = 0
|
||||
@frame = 0
|
||||
@showHP = false # Specifically, show the HP numbers
|
||||
@animatingHP = false
|
||||
@showExp = false # Specifically, show the Exp bar
|
||||
@animatingExp = false
|
||||
@expFlash = 0
|
||||
@battler = battler
|
||||
@sprites = {}
|
||||
@spriteX = 0
|
||||
@spriteY = 0
|
||||
@spriteBaseX = 0
|
||||
@selected = 0
|
||||
@show_hp_numbers = false
|
||||
@show_exp_bar = false
|
||||
initializeDataBoxGraphic(sideSize)
|
||||
initializeOtherGraphics(viewport)
|
||||
refresh
|
||||
@@ -45,8 +47,8 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
bgFilename = ["Graphics/UI/Battle/databox_normal",
|
||||
"Graphics/UI/Battle/databox_normal_foe"][@battler.index % 2]
|
||||
if onPlayerSide
|
||||
@showHP = true
|
||||
@showExp = true
|
||||
@show_hp_numbers = true
|
||||
@show_exp_bar = true
|
||||
end
|
||||
else # Multiple Pokémon on side, use the thin dara box BG
|
||||
bgFilename = ["Graphics/UI/Battle/databox_thin",
|
||||
@@ -143,7 +145,7 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
@sprites.each do |i|
|
||||
i[1].visible = value if !i[1].disposed?
|
||||
end
|
||||
@expBar.visible = (value && @showExp)
|
||||
@expBar.visible = (value && @show_exp_bar)
|
||||
end
|
||||
|
||||
def color=(value)
|
||||
@@ -159,38 +161,46 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
end
|
||||
|
||||
def hp
|
||||
return (@animatingHP) ? @currentHP : @battler.hp
|
||||
return (animating_hp?) ? @anim_hp_current : @battler.hp
|
||||
end
|
||||
|
||||
def exp_fraction
|
||||
return 0.0 if @rangeExp == 0
|
||||
return (@animatingExp) ? @currentExp.to_f / @rangeExp : @battler.pokemon.exp_fraction
|
||||
if animating_exp?
|
||||
return 0.0 if @anim_exp_range == 0
|
||||
return @anim_exp_current.to_f / @anim_exp_range
|
||||
end
|
||||
return @battler.pokemon.exp_fraction
|
||||
end
|
||||
|
||||
def animateHP(oldHP, newHP, rangeHP)
|
||||
@currentHP = oldHP
|
||||
@endHP = newHP
|
||||
@rangeHP = rangeHP
|
||||
# NOTE: A change in HP takes the same amount of time to animate, no matter
|
||||
# how big a change it is.
|
||||
@hpIncPerFrame = (newHP - oldHP).abs / (HP_BAR_CHANGE_TIME * Graphics.frame_rate)
|
||||
# minInc is the smallest amount that HP is allowed to change per frame.
|
||||
# This avoids a tiny change in HP still taking HP_BAR_CHANGE_TIME seconds.
|
||||
minInc = (rangeHP * 4) / (@hpBarBitmap.width * HP_BAR_CHANGE_TIME * Graphics.frame_rate)
|
||||
@hpIncPerFrame = minInc if @hpIncPerFrame < minInc
|
||||
@animatingHP = true
|
||||
# NOTE: A change in HP takes the same amount of time to animate, no matter how
|
||||
# big a change it is.
|
||||
def animate_hp(old_val, new_val)
|
||||
return if old_val == new_val
|
||||
@anim_hp_start = old_val
|
||||
@anim_hp_end = new_val
|
||||
@anim_hp_current = old_val
|
||||
@anim_hp_timer_start = System.uptime
|
||||
end
|
||||
|
||||
def animateExp(oldExp, newExp, rangeExp)
|
||||
return if rangeExp == 0
|
||||
@currentExp = oldExp
|
||||
@endExp = newExp
|
||||
@rangeExp = rangeExp
|
||||
# NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME
|
||||
# seconds no matter what. Filling half of it takes half as long, etc.
|
||||
@expIncPerFrame = rangeExp / (EXP_BAR_FILL_TIME * Graphics.frame_rate)
|
||||
@animatingExp = true
|
||||
pbSEPlay("Pkmn exp gain") if @showExp
|
||||
def animating_hp?
|
||||
return @anim_hp_timer_start != nil
|
||||
end
|
||||
|
||||
# NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME seconds
|
||||
# no matter what. Filling half of it takes half as long, etc.
|
||||
def animate_exp(old_val, new_val, range)
|
||||
return if old_val == new_val || range == 0 || !@show_exp_bar
|
||||
@anim_exp_start = old_val
|
||||
@anim_exp_end = new_val
|
||||
@anim_exp_range = range
|
||||
@anim_exp_duration_mult = (new_val - old_val).abs / range.to_f
|
||||
@anim_exp_current = old_val
|
||||
@anim_exp_timer_start = System.uptime
|
||||
pbSEPlay("Pkmn exp gain") if @show_exp_bar
|
||||
end
|
||||
|
||||
def animating_exp?
|
||||
return @anim_exp_timer_start != nil
|
||||
end
|
||||
|
||||
def pbDrawNumber(number, btmp, startX, startY, align = 0)
|
||||
@@ -284,15 +294,15 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
draw_shiny_icon
|
||||
draw_special_form_icon
|
||||
draw_owned_icon
|
||||
refreshHP
|
||||
refreshExp
|
||||
refresh_hp
|
||||
refresh_exp
|
||||
end
|
||||
|
||||
def refreshHP
|
||||
def refresh_hp
|
||||
@hpNumbers.bitmap.clear
|
||||
return if !@battler.pokemon
|
||||
# Show HP numbers
|
||||
if @showHP
|
||||
if @show_hp_numbers
|
||||
pbDrawNumber(self.hp, @hpNumbers.bitmap, 54, 2, 1)
|
||||
pbDrawNumber(-1, @hpNumbers.bitmap, 54, 2) # / char
|
||||
pbDrawNumber(@battler.totalhp, @hpNumbers.bitmap, 70, 2)
|
||||
@@ -307,14 +317,14 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
w = ((w / 2.0).round) * 2
|
||||
end
|
||||
@hpBar.src_rect.width = w
|
||||
hpColor = 0 # Green bar
|
||||
hpColor = 0 # Green bar
|
||||
hpColor = 1 if self.hp <= @battler.totalhp / 2 # Yellow bar
|
||||
hpColor = 2 if self.hp <= @battler.totalhp / 4 # Red bar
|
||||
@hpBar.src_rect.y = hpColor * @hpBarBitmap.height / 3
|
||||
end
|
||||
|
||||
def refreshExp
|
||||
return if !@showExp
|
||||
def refresh_exp
|
||||
return if !@show_exp_bar
|
||||
w = exp_fraction * @expBarBitmap.width
|
||||
# NOTE: The line below snaps the bar's width to the nearest 2 pixels, to
|
||||
# fit in with the rest of the graphics which are doubled in size.
|
||||
@@ -322,80 +332,82 @@ class Battle::Scene::PokemonDataBox < Sprite
|
||||
@expBar.src_rect.width = w
|
||||
end
|
||||
|
||||
def updateHPAnimation
|
||||
return if !@animatingHP
|
||||
if @currentHP < @endHP # Gaining HP
|
||||
@currentHP += @hpIncPerFrame
|
||||
@currentHP = @endHP if @currentHP >= @endHP
|
||||
elsif @currentHP > @endHP # Losing HP
|
||||
@currentHP -= @hpIncPerFrame
|
||||
@currentHP = @endHP if @currentHP <= @endHP
|
||||
end
|
||||
def update_hp_animation
|
||||
return if !animating_hp?
|
||||
@anim_hp_current = lerp(@anim_hp_start, @anim_hp_end, HP_BAR_CHANGE_TIME,
|
||||
@anim_hp_timer_start, System.uptime)
|
||||
# Refresh the HP bar/numbers
|
||||
refreshHP
|
||||
@animatingHP = false if @currentHP == @endHP
|
||||
refresh_hp
|
||||
# End the HP bar filling animation
|
||||
if @anim_hp_current == @anim_hp_end
|
||||
@anim_hp_start = nil
|
||||
@anim_hp_end = nil
|
||||
@anim_hp_timer_start = nil
|
||||
@anim_hp_current = nil
|
||||
end
|
||||
end
|
||||
|
||||
def updateExpAnimation
|
||||
return if !@animatingExp
|
||||
if !@showExp # Not showing the Exp bar, no need to waste time animating it
|
||||
@currentExp = @endExp
|
||||
@animatingExp = false
|
||||
def update_exp_animation
|
||||
return if !animating_exp?
|
||||
if !@show_exp_bar # Not showing the Exp bar, no need to waste time animating it
|
||||
@anim_exp_timer_start = nil
|
||||
return
|
||||
end
|
||||
if @currentExp < @endExp # Gaining Exp
|
||||
@currentExp += @expIncPerFrame
|
||||
@currentExp = @endExp if @currentExp >= @endExp
|
||||
elsif @currentExp > @endExp # Losing Exp
|
||||
@currentExp -= @expIncPerFrame
|
||||
@currentExp = @endExp if @currentExp <= @endExp
|
||||
end
|
||||
duration = EXP_BAR_FILL_TIME * @anim_exp_duration_mult
|
||||
@anim_exp_current = lerp(@anim_exp_start, @anim_exp_end, duration,
|
||||
@anim_exp_timer_start, System.uptime)
|
||||
# Refresh the Exp bar
|
||||
refreshExp
|
||||
return if @currentExp != @endExp # Exp bar still has more to animate
|
||||
# Exp bar is completely filled, level up with a flash and sound effect
|
||||
if @currentExp >= @rangeExp
|
||||
if @expFlash == 0
|
||||
pbSEStop
|
||||
@expFlash = Graphics.frame_rate / 5
|
||||
pbSEPlay("Pkmn exp full")
|
||||
self.flash(Color.new(64, 200, 248, 192), @expFlash)
|
||||
@sprites.each do |i|
|
||||
i[1].flash(Color.new(64, 200, 248, 192), @expFlash) if !i[1].disposed?
|
||||
end
|
||||
refresh_exp
|
||||
return if @anim_exp_current != @anim_exp_end # Exp bar still has more to animate
|
||||
# End the Exp bar filling animation
|
||||
if @anim_exp_current >= @anim_exp_range
|
||||
if @anim_exp_flash_timer_start
|
||||
# Waiting for Exp full flash to finish
|
||||
return if System.uptime - @anim_exp_flash_timer_start < EXP_FULL_FLASH_DURATION
|
||||
else
|
||||
@expFlash -= 1
|
||||
@animatingExp = false if @expFlash == 0
|
||||
# Show the Exp full flash
|
||||
@anim_exp_flash_timer_start = System.uptime
|
||||
pbSEStop
|
||||
pbSEPlay("Pkmn exp full")
|
||||
flash_duration = EXP_FULL_FLASH_DURATION * Graphics.frame_rate # Must be in frames, not seconds
|
||||
self.flash(Color.new(64, 200, 248, 192), flash_duration)
|
||||
@sprites.each do |i|
|
||||
i[1].flash(Color.new(64, 200, 248, 192), flash_duration) if !i[1].disposed?
|
||||
end
|
||||
return
|
||||
end
|
||||
else
|
||||
pbSEStop
|
||||
# Exp bar has finished filling, end animation
|
||||
@animatingExp = false
|
||||
end
|
||||
pbSEStop if !@anim_exp_flash_timer_start
|
||||
@anim_exp_start = nil
|
||||
@anim_exp_end = nil
|
||||
@anim_exp_duration_mult = nil
|
||||
@anim_exp_current = nil
|
||||
@anim_exp_timer_start = nil
|
||||
@anim_exp_flash_timer_start = nil
|
||||
end
|
||||
|
||||
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20
|
||||
|
||||
def updatePositions(frameCounter)
|
||||
def update_positions
|
||||
self.x = @spriteX
|
||||
self.y = @spriteY
|
||||
# Data box bobbing while Pokémon is selected
|
||||
if @selected == 1 || @selected == 2 # Choosing commands/targeted or damaged
|
||||
case (frameCounter / QUARTER_ANIM_PERIOD).floor
|
||||
if (@selected == 1 || @selected == 2) && BOBBING_DURATION # Choosing commands/targeted
|
||||
bob_delta = System.uptime % BOBBING_DURATION # 0-BOBBING_DURATION
|
||||
bob_frame = (4 * bob_delta / BOBBING_DURATION).floor
|
||||
case bob_frame
|
||||
when 1 then self.y = @spriteY - 2
|
||||
when 3 then self.y = @spriteY + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update(frameCounter = 0)
|
||||
super()
|
||||
def update
|
||||
super
|
||||
# Animate HP bar
|
||||
updateHPAnimation
|
||||
update_hp_animation
|
||||
# Animate Exp bar
|
||||
updateExpAnimation
|
||||
update_exp_animation
|
||||
# Update coordinates of the data box
|
||||
updatePositions(frameCounter)
|
||||
update_positions
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
end
|
||||
end
|
||||
@@ -502,6 +514,13 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
||||
attr_accessor :selected
|
||||
attr_reader :sideSize
|
||||
|
||||
# Time (in seconds) for one complete sprite bob cycle (up and down) while
|
||||
# choosing a command for this battler. Set to nil to prevent bobbing.
|
||||
COMMAND_BOBBING_DURATION = 0.6
|
||||
# Time (in seconds) for one complete blinking cycle while this battler is
|
||||
# being chosen as a target. Set to nil to prevent blinking.
|
||||
TARGET_BLINKING_DURATION = 0.3
|
||||
|
||||
def initialize(viewport, sideSize, index, battleAnimations)
|
||||
super(viewport)
|
||||
@pkmn = nil
|
||||
@@ -511,7 +530,6 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
||||
# @selected: 0 = not selected, 1 = choosing action bobbing for this Pokémon,
|
||||
# 2 = flashing when targeted
|
||||
@selected = 0
|
||||
@frame = 0
|
||||
@updating = false
|
||||
@spriteX = 0 # Actual x coordinate
|
||||
@spriteY = 0 # Actual y coordinate
|
||||
@@ -588,10 +606,7 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
||||
@pkmn&.play_cry
|
||||
end
|
||||
|
||||
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20
|
||||
SIXTH_ANIM_PERIOD = Graphics.frame_rate * 2 / 20
|
||||
|
||||
def update(frameCounter = 0)
|
||||
def update
|
||||
return if !@_iconBitmap
|
||||
@updating = true
|
||||
# Update bitmap
|
||||
@@ -599,8 +614,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
||||
self.bitmap = @_iconBitmap.bitmap
|
||||
# Pokémon sprite bobbing while Pokémon is selected
|
||||
@spriteYExtra = 0
|
||||
if @selected == 1 # When choosing commands for this Pokémon
|
||||
case (frameCounter / QUARTER_ANIM_PERIOD).floor
|
||||
if @selected == 1 && COMMAND_BOBBING_DURATION # When choosing commands for this Pokémon
|
||||
bob_delta = System.uptime % COMMAND_BOBBING_DURATION # 0-COMMAND_BOBBING_DURATION
|
||||
bob_frame = (4 * bob_delta / COMMAND_BOBBING_DURATION).floor
|
||||
case bob_frame
|
||||
when 1 then @spriteYExtra = 2
|
||||
when 3 then @spriteYExtra = -2
|
||||
end
|
||||
@@ -609,11 +626,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
|
||||
self.y = self.y
|
||||
self.visible = @spriteVisible
|
||||
# Pokémon sprite blinking when targeted
|
||||
if @selected == 2 && @spriteVisible
|
||||
case (frameCounter / SIXTH_ANIM_PERIOD).floor
|
||||
when 2, 5 then self.visible = false
|
||||
else self.visible = true
|
||||
end
|
||||
if @selected == 2 && @spriteVisible && TARGET_BLINKING_DURATION
|
||||
blink_delta = System.uptime % TARGET_BLINKING_DURATION # 0-TARGET_BLINKING_DURATION
|
||||
blink_frame = (3 * blink_delta / TARGET_BLINKING_DURATION).floor
|
||||
self.visible = (blink_frame != 0)
|
||||
end
|
||||
@updating = false
|
||||
end
|
||||
@@ -673,7 +689,7 @@ class Battle::Scene::BattlerShadowSprite < RPG::Sprite
|
||||
pbSetPosition
|
||||
end
|
||||
|
||||
def update(frameCounter = 0)
|
||||
def update
|
||||
return if !@_iconBitmap
|
||||
# Update bitmap
|
||||
@_iconBitmap.update
|
||||
|
||||
Reference in New Issue
Block a user