More FPS agnosticism, fixed pause after finishing an event's repeating move route

This commit is contained in:
Maruno17
2023-05-24 21:20:20 +01:00
parent 167155c67d
commit c756e2647a
30 changed files with 947 additions and 847 deletions

View File

@@ -389,14 +389,3 @@ end
def nil_or_empty?(string) def nil_or_empty?(string)
return string.nil? || !string.is_a?(String) || string.size == 0 return string.nil? || !string.is_a?(String) || string.size == 0
end end
# Linear interpolation between two values, given the duration of the change and
# either:
# - the time passed since the start of the change (delta), or
# - the start time of the change (delta) and the current time (now)
def lerp(start_val, end_val, duration, delta, now = nil)
delta = now - delta if now
return start_val if delta <= 0
return end_val if delta >= duration
return start_val + (end_val - start_val) * delta / duration
end

View File

@@ -1,88 +1,52 @@
#===============================================================================
# Linear interpolation between two values, given the duration of the change and
# either:
# - the time passed since the start of the change (delta), or
# - the start time of the change (delta) and the current time (now)
#===============================================================================
def lerp(start_val, end_val, duration, delta, now = nil)
delta = now - delta if now
return start_val if delta <= 0
return end_val if delta >= duration
return start_val + (end_val - start_val) * delta / duration
end
#=============================================================================== #===============================================================================
# #
#=============================================================================== #===============================================================================
class Interpolator class PointInterpolator
ZOOM_X = 1 attr_reader :x
ZOOM_Y = 2 attr_reader :y
X = 3
Y = 4
OPACITY = 5
COLOR = 6
WAIT = 7
def initialize def initialize(oldx, oldy, newx, newy, frames)
@tweening = false restart(oldx, oldy, newx, newy, frames)
@tweensteps = []
@sprite = nil
@frames = 0
@step = 0
end end
def tweening? def restart(oldx, oldy, newx, newy, frames)
return @tweening @oldx = oldx
end @oldy = oldy
@newx = newx
def tween(sprite, items, frames) @newy = newy
@tweensteps = []
if sprite && !sprite.disposed? && frames > 0
@frames = frames @frames = frames
@step = 0 @curframe = 0
@sprite = sprite @x = oldx
items.each do |item| @y = oldy
case item[0]
when ZOOM_X
@tweensteps[item[0]] = [sprite.zoom_x, item[1] - sprite.zoom_x]
when ZOOM_Y
@tweensteps[item[0]] = [sprite.zoom_y, item[1] - sprite.zoom_y]
when X
@tweensteps[item[0]] = [sprite.x, item[1] - sprite.x]
when Y
@tweensteps[item[0]] = [sprite.y, item[1] - sprite.y]
when OPACITY
@tweensteps[item[0]] = [sprite.opacity, item[1] - sprite.opacity]
when COLOR
@tweensteps[item[0]] = [sprite.color.clone,
Color.new(item[1].red - sprite.color.red,
item[1].green - sprite.color.green,
item[1].blue - sprite.color.blue,
item[1].alpha - sprite.color.alpha)]
end
end
@tweening = true
end end
def done?
@curframe > @frames
end end
def update def update
if @tweening return if done?
t = @step.to_f / @frames t = @curframe.to_f / @frames
@tweensteps.length.times do |i| rx1 = @oldx
item = @tweensteps[i] rx2 = @newx
next if !item @x = rx1 + (t * (rx2 - rx1))
case i ry1 = @oldy
when ZOOM_X ry2 = @newy
@sprite.zoom_x = item[0] + (item[1] * t) @y = ry1 + (t * (ry2 - ry1))
when ZOOM_Y @curframe += 1
@sprite.zoom_y = item[0] + (item[1] * t)
when X
@sprite.x = item[0] + (item[1] * t)
when Y
@sprite.y = item[0] + (item[1] * t)
when OPACITY
@sprite.opacity = item[0] + (item[1] * t)
when COLOR
@sprite.color = Color.new(item[0].red + (item[1].red * t),
item[0].green + (item[1].green * t),
item[0].blue + (item[1].blue * t),
item[0].alpha + (item[1].alpha * t))
end
end
@step += 1
if @step == @frames
@step = 0
@frames = 0
@tweening = false
end
end
end end
end end
@@ -137,38 +101,86 @@ end
#=============================================================================== #===============================================================================
# #
#=============================================================================== #===============================================================================
class PointInterpolator class SpriteInterpolator
attr_reader :x X = 1
attr_reader :y Y = 2
ZOOM_X = 3
ZOOM_Y = 4
COLOR = 5
OPACITY = 6
def initialize(oldx, oldy, newx, newy, frames) def initialize
restart(oldx, oldy, newx, newy, frames) @tweening = false
@tweensteps = []
@sprite = nil
@frames = 0
@step = 0
end end
def restart(oldx, oldy, newx, newy, frames) def tweening?
@oldx = oldx return @tweening
@oldy = oldy end
@newx = newx
@newy = newy def tween(sprite, items, frames)
@tweensteps = []
if sprite && !sprite.disposed? && frames > 0
@frames = frames @frames = frames
@curframe = 0 @step = 0
@x = oldx @sprite = sprite
@y = oldy items.each do |item|
case item[0]
when X
@tweensteps[item[0]] = [sprite.x, item[1] - sprite.x]
when Y
@tweensteps[item[0]] = [sprite.y, item[1] - sprite.y]
when ZOOM_X
@tweensteps[item[0]] = [sprite.zoom_x, item[1] - sprite.zoom_x]
when ZOOM_Y
@tweensteps[item[0]] = [sprite.zoom_y, item[1] - sprite.zoom_y]
when COLOR
@tweensteps[item[0]] = [sprite.color.clone,
Color.new(item[1].red - sprite.color.red,
item[1].green - sprite.color.green,
item[1].blue - sprite.color.blue,
item[1].alpha - sprite.color.alpha)]
when OPACITY
@tweensteps[item[0]] = [sprite.opacity, item[1] - sprite.opacity]
end
end
@tweening = true
end end
def done?
@curframe > @frames
end end
def update def update
return if done? if @tweening
t = @curframe.to_f / @frames t = @step.to_f / @frames
rx1 = @oldx @tweensteps.length.times do |i|
rx2 = @newx item = @tweensteps[i]
@x = rx1 + (t * (rx2 - rx1)) next if !item
ry1 = @oldy case i
ry2 = @newy when X
@y = ry1 + (t * (ry2 - ry1)) @sprite.x = item[0] + (item[1] * t)
@curframe += 1 when Y
@sprite.y = item[0] + (item[1] * t)
when ZOOM_X
@sprite.zoom_x = item[0] + (item[1] * t)
when ZOOM_Y
@sprite.zoom_y = item[0] + (item[1] * t)
when COLOR
@sprite.color = Color.new(item[0].red + (item[1].red * t),
item[0].green + (item[1].green * t),
item[0].blue + (item[1].blue * t),
item[0].alpha + (item[1].alpha * t))
when OPACITY
@sprite.opacity = item[0] + (item[1] * t)
end
end
@step += 1
if @step == @frames
@step = 0
@frames = 0
@tweening = false
end
end
end end
end end

View File

@@ -416,8 +416,8 @@ class Interpreter
result = ($game_self_switches[key] == (@parameters[2] == 0)) result = ($game_self_switches[key] == (@parameters[2] == 0))
end end
when 3 # timer when 3 # timer
if $game_system.timer_working if $game_system.timer_start
sec = $game_system.timer / Graphics.frame_rate sec = $game_system.timer
result = (@parameters[2] == 0) ? (sec >= @parameters[1]) : (sec <= @parameters[1]) result = (@parameters[2] == 0) ? (sec >= @parameters[1]) : (sec <= @parameters[1])
end end
# when 4, 5 # actor, enemy # when 4, 5 # actor, enemy
@@ -591,9 +591,9 @@ class Interpreter
when 0 then value = $game_map.map_id # map ID when 0 then value = $game_map.map_id # map ID
when 1 then value = $player.pokemon_party.length # party members when 1 then value = $player.pokemon_party.length # party members
when 2 then value = $player.money # gold when 2 then value = $player.money # gold
# when 3 # steps when 3 then value = $stats.distance_moved # steps
when 4 then value = Graphics.frame_count / Graphics.frame_rate # play time when 4 then value = $stats.play_time # play time
when 5 then value = $game_system.timer / Graphics.frame_rate # timer when 5 then value = $game_system.timer # timer
when 6 then value = $game_system.save_count # save count when 6 then value = $game_system.save_count # save count
end end
end end
@@ -645,8 +645,8 @@ class Interpreter
# * Control Timer # * Control Timer
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_124 def command_124
$game_system.timer_working = (@parameters[0] == 0) $game_system.timer_start = (@parameters[0] == 0) ? $stats.play_time : nil
$game_system.timer = @parameters[1] * Graphics.frame_rate if @parameters[0] == 0 $game_system.timer_duration = @parameters[1] if @parameters[0] == 0
return true return true
end end
@@ -815,7 +815,7 @@ class Interpreter
# * Change Fog Color Tone # * Change Fog Color Tone
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_205 def command_205
$game_map.start_fog_tone_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) $game_map.start_fog_tone_change(@parameters[0], @parameters[1])
return true return true
end end
@@ -823,7 +823,7 @@ class Interpreter
# * Change Fog Opacity # * Change Fog Opacity
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_206 def command_206
$game_map.start_fog_opacity_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) $game_map.start_fog_opacity_change(@parameters[0], @parameters[1])
return true return true
end end
@@ -897,7 +897,7 @@ class Interpreter
# * Change Screen Color Tone # * Change Screen Color Tone
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_223 def command_223
$game_screen.start_tone_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) $game_screen.start_tone_change(@parameters[0], @parameters[1])
return true return true
end end
@@ -905,7 +905,7 @@ class Interpreter
# * Screen Flash # * Screen Flash
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_224 def command_224
$game_screen.start_flash(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) $game_screen.start_flash(@parameters[0], @parameters[1])
return true return true
end end
@@ -946,8 +946,9 @@ class Interpreter
x = $game_variables[@parameters[4]] x = $game_variables[@parameters[4]]
y = $game_variables[@parameters[5]] y = $game_variables[@parameters[5]]
end end
$game_screen.pictures[number].move(@parameters[1] * Graphics.frame_rate / 20, $game_screen.pictures[number].move(@parameters[1], @parameters[2], x, y,
@parameters[2], x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9]) @parameters[6], @parameters[7],
@parameters[8], @parameters[9])
return true return true
end end
@@ -965,8 +966,7 @@ class Interpreter
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def command_234 def command_234
number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) number = @parameters[0] + ($game_temp.in_battle ? 50 : 0)
$game_screen.pictures[number].start_tone_change(@parameters[1], $game_screen.pictures[number].start_tone_change(@parameters[1], @parameters[2])
@parameters[2] * Graphics.frame_rate / 20)
return true return true
end end

View File

@@ -21,31 +21,40 @@ class Game_Screen
@tone = Tone.new(0, 0, 0, 0) @tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0) @tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0 @tone_duration = 0
@tone_timer_start = nil
@flash_color = Color.new(0, 0, 0, 0) @flash_color = Color.new(0, 0, 0, 0)
@flash_duration = 0 @flash_duration = 0
@flash_timer_start = nil
@shake_power = 0 @shake_power = 0
@shake_speed = 0 @shake_speed = 0
@shake_duration = 0 @shake_duration = 0
@shake_direction = 1 @shake_direction = 1
@shake = 0 @shake = 0
@pictures = [nil] @pictures = [nil]
(1..100).each do |i| (1..100).each { |i| @pictures.push(Game_Picture.new(i)) }
@pictures.push(Game_Picture.new(i))
end
@weather_type = :None @weather_type = :None
@weather_max = 0.0 @weather_max = 0.0
@weather_duration = 0 @weather_duration = 0
end end
# duration is time in 1/20ths of a second.
def start_tone_change(tone, duration) def start_tone_change(tone, duration)
if duration == 0
@tone = tone.clone
return
end
@tone_initial = @tone.clone
@tone_target = tone.clone @tone_target = tone.clone
@tone_duration = duration @tone_duration = duration / 20.0
@tone = @tone_target.clone if @tone_duration == 0 @tone_timer_start = $stats.play_time
end end
# duration is time in 1/20ths of a second.
def start_flash(color, duration) def start_flash(color, duration)
@flash_color = color.clone @flash_color = color.clone
@flash_duration = duration @flash_initial_alpha = @flash_color.alpha
@flash_duration = duration / 20.0
@flash_timer_start = $stats.play_time
end end
def start_shake(power, speed, duration) def start_shake(power, speed, duration)
@@ -71,18 +80,23 @@ class Game_Screen
@brightness = ((@brightness * (d - 1)) + 255) / d @brightness = ((@brightness * (d - 1)) + 255) / d
@fadein_duration -= 1 @fadein_duration -= 1
end end
if @tone_duration >= 1 now = $stats.play_time
d = @tone_duration if @tone_timer_start
@tone.red = ((@tone.red * (d - 1)) + @tone_target.red) / d @tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now)
@tone.green = ((@tone.green * (d - 1)) + @tone_target.green) / d @tone.green = lerp(@tone_initial.green, @tone_target.green, @tone_duration, @tone_timer_start, now)
@tone.blue = ((@tone.blue * (d - 1)) + @tone_target.blue) / d @tone.blue = lerp(@tone_initial.blue, @tone_target.blue, @tone_duration, @tone_timer_start, now)
@tone.gray = ((@tone.gray * (d - 1)) + @tone_target.gray) / d @tone.gray = lerp(@tone_initial.gray, @tone_target.gray, @tone_duration, @tone_timer_start, now)
@tone_duration -= 1 if now - @tone_timer_start >= @tone_duration
@tone_initial = nil
@tone_timer_start = nil
end
end
if @flash_timer_start
@flash_color.alpha = lerp(@flash_initial_alpha, 0, @flash_duration, @flash_timer_start, now)
if now - @flash_timer_start >= @flash_duration
@flash_initial_alpha = nil
@flash_timer_start = nil
end end
if @flash_duration >= 1
d = @flash_duration
@flash_color.alpha = @flash_color.alpha * (d - 1) / d
@flash_duration -= 1
end end
if @shake_duration >= 1 || @shake != 0 if @shake_duration >= 1 || @shake != 0
delta = (@shake_power * @shake_speed * @shake_direction) / 10.0 delta = (@shake_power * @shake_speed * @shake_direction) / 10.0
@@ -96,13 +110,9 @@ class Game_Screen
@shake_duration -= 1 if @shake_duration >= 1 @shake_duration -= 1 if @shake_duration >= 1
end end
if $game_temp.in_battle if $game_temp.in_battle
(51..100).each do |i| (51..100).each { |i| @pictures[i].update }
@pictures[i].update
end
else else
(1..50).each do |i| (1..50).each { |i| @pictures[i].update }
@pictures[i].update
end
end end
end end
end end
@@ -111,16 +121,14 @@ end
# #
#=============================================================================== #===============================================================================
def pbToneChangeAll(tone, duration) def pbToneChangeAll(tone, duration)
$game_screen.start_tone_change(tone, duration * Graphics.frame_rate / 20) $game_screen.start_tone_change(tone, duration)
$game_screen.pictures.each do |picture| $game_screen.pictures.each { |picture| picture&.start_tone_change(tone, duration) }
picture&.start_tone_change(tone, duration * Graphics.frame_rate / 20) end
end
def pbFlash(color, frames)
$game_screen.start_flash(color, frames)
end end
def pbShake(power, speed, frames) def pbShake(power, speed, frames)
$game_screen.start_shake(power, speed, frames * Graphics.frame_rate / 20) $game_screen.start_shake(power, speed, frames * Graphics.frame_rate / 20)
end end
def pbFlash(color, frames)
$game_screen.start_flash(color, frames * Graphics.frame_rate / 20)
end

View File

@@ -8,8 +8,8 @@
class Game_System class Game_System
attr_reader :map_interpreter # map event interpreter attr_reader :map_interpreter # map event interpreter
attr_reader :battle_interpreter # battle event interpreter attr_reader :battle_interpreter # battle event interpreter
attr_accessor :timer # timer attr_accessor :timer_start # $stats.play_time when timer was started, or nil
attr_accessor :timer_working # timer working flag attr_accessor :timer_duration # Time (in seconds) the timer is initially set to
attr_accessor :save_disabled # save forbidden attr_accessor :save_disabled # save forbidden
attr_accessor :menu_disabled # menu forbidden attr_accessor :menu_disabled # menu forbidden
attr_accessor :encounter_disabled # encounter forbidden attr_accessor :encounter_disabled # encounter forbidden
@@ -24,8 +24,8 @@ class Game_System
def initialize def initialize
@map_interpreter = Interpreter.new(0, true) @map_interpreter = Interpreter.new(0, true)
@battle_interpreter = Interpreter.new(0, false) @battle_interpreter = Interpreter.new(0, false)
@timer = 0 @timer_start = nil
@timer_working = false @timer_duration = 0
@save_disabled = false @save_disabled = false
@menu_disabled = false @menu_disabled = false
@encounter_disabled = false @encounter_disabled = false
@@ -265,17 +265,18 @@ class Game_System
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def windowskin_name def windowskin_name
if @windowskin_name.nil? return $data_system.windowskin_name if @windowskin_name.nil?
return $data_system.windowskin_name
else
return @windowskin_name return @windowskin_name
end end
end
attr_writer :windowskin_name attr_writer :windowskin_name
def timer
return 0 if !@timer_start || !$stats
return @timer_duration - $stats.play_time + @timer_start
end
def update def update
@timer -= 1 if @timer_working && @timer > 0
if Input.trigger?(Input::SPECIAL) && pbCurrentEventCommentInput(1, "Cut Scene") if Input.trigger?(Input::SPECIAL) && pbCurrentEventCommentInput(1, "Cut Scene")
event = @map_interpreter.get_self event = @map_interpreter.get_self
@map_interpreter.pbSetSelfSwitch(event.id, "A", true) @map_interpreter.pbSetSelfSwitch(event.id, "A", true)

View File

@@ -28,6 +28,7 @@ class Game_Picture
@opacity = 255.0 @opacity = 255.0
@blend_type = 1 @blend_type = 1
@duration = 0 @duration = 0
@move_timer_start = nil
@target_x = @x @target_x = @x
@target_y = @y @target_y = @y
@target_zoom_x = @zoom_x @target_zoom_x = @zoom_x
@@ -36,6 +37,7 @@ class Game_Picture
@tone = Tone.new(0, 0, 0, 0) @tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0) @tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0 @tone_duration = 0
@tone_timer_start = nil
@angle = 0 @angle = 0
@rotate_speed = 0 @rotate_speed = 0
end end
@@ -67,12 +69,13 @@ class Game_Picture
@tone = Tone.new(0, 0, 0, 0) @tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0) @tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0 @tone_duration = 0
@tone_timer_start = nil
@angle = 0 @angle = 0
@rotate_speed = 0 @rotate_speed = 0
end end
# Move Picture # Move Picture
# duration : time # duration : time in 1/20ths of a second
# origin : starting point # origin : starting point
# x : x-coordinate # x : x-coordinate
# y : y-coordinate # y : y-coordinate
@@ -81,57 +84,79 @@ class Game_Picture
# opacity : opacity level # opacity : opacity level
# blend_type : blend method # blend_type : blend method
def move(duration, origin, x, y, zoom_x, zoom_y, opacity, blend_type) def move(duration, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
@duration = duration @duration = duration / 20.0
@origin = origin @origin = origin
@initial_x = @x
@initial_y = @y
@target_x = x.to_f @target_x = x.to_f
@target_y = y.to_f @target_y = y.to_f
@initial_zoom_x = @zoom_x
@initial_zoom_y = @zoom_y
@target_zoom_x = zoom_x.to_f @target_zoom_x = zoom_x.to_f
@target_zoom_y = zoom_y.to_f @target_zoom_y = zoom_y.to_f
@initial_opacity = @opacity
@target_opacity = opacity.to_f @target_opacity = opacity.to_f
@blend_type = blend_type || 0 @blend_type = blend_type || 0
@move_timer_start = $stats.play_time
end end
# Change Rotation Speed # Change Rotation Speed
# speed : rotation speed # speed : rotation speed (degrees to change per 1/20th of a second)
def rotate(speed) def rotate(speed)
@rotate_timer = (speed == 0) ? nil : System.uptime # Time since last frame
@rotate_speed = speed @rotate_speed = speed
end end
# Start Change of Color Tone # Start Change of Color Tone
# tone : color tone # tone : color tone
# duration : time # duration : time in 1/20ths of a second
def start_tone_change(tone, duration) def start_tone_change(tone, duration)
if duration == 0
@tone = tone.clone
return
end
@tone_initial = @tone.clone
@tone_target = tone.clone @tone_target = tone.clone
@tone_duration = duration @tone_duration = duration / 20.0
@tone = @tone_target.clone if @tone_duration == 0 @tone_timer_start = $stats.play_time
end end
# Erase Picture
def erase def erase
@name = "" @name = ""
end end
# Frame Update
def update def update
if @duration >= 1 return if @name == ""
d = @duration now = $stats.play_time
@x = ((@x * (d - 1)) + @target_x) / d if @move_timer_start
@y = ((@y * (d - 1)) + @target_y) / d @x = lerp(@initial_x, @target_x, @duration, @move_timer_start, now)
@zoom_x = ((@zoom_x * (d - 1)) + @target_zoom_x) / d @y = lerp(@initial_y, @target_y, @duration, @move_timer_start, now)
@zoom_y = ((@zoom_y * (d - 1)) + @target_zoom_y) / d @zoom_x = lerp(@initial_zoom_x, @target_zoom_x, @duration, @move_timer_start, now)
@opacity = ((@opacity * (d - 1)) + @target_opacity) / d @zoom_y = lerp(@initial_zoom_y, @target_zoom_y, @duration, @move_timer_start, now)
@duration -= 1 @opacity = lerp(@initial_opacity, @target_opacity, @duration, @move_timer_start, now)
if now - @move_timer_start >= @duration
@initial_x = nil
@initial_y = nil
@initial_zoom_x = nil
@initial_zoom_y = nil
@initial_opacity = nil
@move_timer_start = nil
end
end
if @tone_timer_start
@tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now)
@tone.green = lerp(@tone_initial.green, @tone_target.green, @tone_duration, @tone_timer_start, now)
@tone.blue = lerp(@tone_initial.blue, @tone_target.blue, @tone_duration, @tone_timer_start, now)
@tone.gray = lerp(@tone_initial.gray, @tone_target.gray, @tone_duration, @tone_timer_start, now)
if now - @tone_timer_start >= @tone_duration
@tone_initial = nil
@tone_timer_start = nil
end end
if @tone_duration >= 1
d = @tone_duration
@tone.red = ((@tone.red * (d - 1)) + @tone_target.red) / d
@tone.green = ((@tone.green * (d - 1)) + @tone_target.green) / d
@tone.blue = ((@tone.blue * (d - 1)) + @tone_target.blue) / d
@tone.gray = ((@tone.gray * (d - 1)) + @tone_target.gray) / d
@tone_duration -= 1
end end
if @rotate_speed != 0 if @rotate_speed != 0
@angle += @rotate_speed / 2.0 @rotate_timer = System.uptime if !@rotate_timer
@angle += @rotate_speed * (System.uptime - @rotate_timer) * 20.0
@rotate_timer = System.uptime
while @angle < 0 while @angle < 0
@angle += 360 @angle += 360
end end

View File

@@ -52,8 +52,10 @@ class Game_Map
@fog_tone = Tone.new(0, 0, 0, 0) @fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0) @fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0 @fog_tone_duration = 0
@fog_tone_timer_start = nil
@fog_opacity_duration = 0 @fog_opacity_duration = 0
@fog_opacity_target = 0 @fog_opacity_target = 0
@fog_opacity_timer_start = nil
self.display_x = 0 self.display_x = 0
self.display_y = 0 self.display_y = 0
@need_refresh = false @need_refresh = false
@@ -368,16 +370,28 @@ class Game_Map
return @scroll_rest > 0 return @scroll_rest > 0
end end
# duration is time in 1/20ths of a second.
def start_fog_tone_change(tone, duration) def start_fog_tone_change(tone, duration)
if duration == 0
@fog_tone = tone.clone
return
end
@fog_tone_initial = @fog_tone.clone
@fog_tone_target = tone.clone @fog_tone_target = tone.clone
@fog_tone_duration = duration @fog_tone_duration = duration / 20.0
@fog_tone = @fog_tone_target.clone if @fog_tone_duration == 0 @fog_tone_timer_start = $stats.play_time
end end
# duration is time in 1/20ths of a second.
def start_fog_opacity_change(opacity, duration) def start_fog_opacity_change(opacity, duration)
if duration == 0
@fog_opacity = opacity.to_f
return
end
@fog_opacity_initial = @fog_opacity
@fog_opacity_target = opacity.to_f @fog_opacity_target = opacity.to_f
@fog_opacity_duration = duration @fog_opacity_duration = duration / 20.0
@fog_opacity = @fog_opacity_target if @fog_opacity_duration == 0 @fog_opacity_timer_start = $stats.play_time
end end
def set_tile(x, y, layer, id = 0) def set_tile(x, y, layer, id = 0)
@@ -399,11 +413,9 @@ class Game_Map
end end
def update def update
# refresh maps if necessary # Refresh maps if necessary
if $map_factory if $map_factory
$map_factory.maps.each do |i| $map_factory.maps.each { |i| i.refresh if i.need_refresh }
i.refresh if i.need_refresh
end
$map_factory.setCurrentMap $map_factory.setCurrentMap
end end
# If scrolling # If scrolling
@@ -419,29 +431,31 @@ class Game_Map
@scroll_rest -= distance @scroll_rest -= distance
end end
# Only update events that are on-screen # Only update events that are on-screen
@events.each_value do |event| if !$game_temp.in_menu
event.update @events.each_value { |event| event.update }
end end
# Update common events # Update common events
@common_events.each_value do |common_event| @common_events.each_value { |common_event| common_event.update }
common_event.update
end
# Update fog # Update fog
now = $stats.play_time
@fog_ox -= @fog_sx / 8.0 @fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0 @fog_oy -= @fog_sy / 8.0
if @fog_tone_duration >= 1 if @fog_tone_timer_start
d = @fog_tone_duration @fog_tone.red = lerp(@fog_tone_initial.red, @fog_tone_target.red, @fog_tone_duration, @fog_tone_timer_start, now)
target = @fog_tone_target @fog_tone.green = lerp(@fog_tone_initial.green, @fog_tone_target.green, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.red = ((@fog_tone.red * (d - 1)) + target.red) / d @fog_tone.blue = lerp(@fog_tone_initial.blue, @fog_tone_target.blue, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.green = ((@fog_tone.green * (d - 1)) + target.green) / d @fog_tone.gray = lerp(@fog_tone_initial.gray, @fog_tone_target.gray, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.blue = ((@fog_tone.blue * (d - 1)) + target.blue) / d if now - @fog_tone_timer_start >= @fog_tone_duration
@fog_tone.gray = ((@fog_tone.gray * (d - 1)) + target.gray) / d @fog_tone_initial = nil
@fog_tone_duration -= 1 @fog_tone_timer_start = nil
end
end
if @fog_opacity_timer_start
@fog_opacity = lerp(@fog_opacity_initial, @fog_opacity_target, @fog_opacity_duration, @fog_opacity_timer_start, now)
if now - @fog_opacity_timer_start >= @fog_opacity_duration
@fog_opacity_initial = nil
@fog_opacity_timer_start = nil
end end
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = ((@fog_opacity * (d - 1)) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end end
end end
end end

View File

@@ -25,6 +25,7 @@ class Game_Character
attr_accessor :animation_id attr_accessor :animation_id
attr_accessor :transparent attr_accessor :transparent
attr_reader :move_speed attr_reader :move_speed
attr_accessor :jump_speed
attr_accessor :walk_anime attr_accessor :walk_anime
attr_writer :bob_height attr_writer :bob_height
@@ -60,6 +61,7 @@ class Game_Character
@move_type = 0 @move_type = 0
self.move_speed = 3 self.move_speed = 3
self.move_frequency = 6 self.move_frequency = 6
self.jump_speed = 3
@move_route = nil @move_route = nil
@move_route_index = 0 @move_route_index = 0
@original_move_route = nil @original_move_route = nil
@@ -68,12 +70,12 @@ class Game_Character
@step_anime = false # Whether character should animate while still @step_anime = false # Whether character should animate while still
@direction_fix = false @direction_fix = false
@always_on_top = false @always_on_top = false
@anime_count = 0 @anime_count = 0 # Time since pattern was last changed
@stop_count = 0 @stop_count = 0 # Time since character last finished moving
@jump_peak = 0 # Max height while jumping @jump_peak = 0 # Max height while jumping
@jump_distance = 0 # Total distance of jump @jump_distance = 0 # Total distance of jump
@jump_distance_left = 0 # Distance left to travel @jump_fraction = 0 # How far through a jump we currently are (0-1)
@jump_count = 0 # Frames left in a stationary jump @jumping_on_spot = false
@bob_height = 0 @bob_height = 0
@wait_count = 0 @wait_count = 0
@wait_start = nil @wait_start = nil
@@ -105,62 +107,45 @@ class Game_Character
end end
def move_speed=(val) def move_speed=(val)
return if val == @move_speed
@move_speed = val @move_speed = val
# @move_speed_real is the number of quarter-pixels to move each frame. There # Time taken to traverse one tile (in seconds) for each speed:
# are 128 quarter-pixels per tile. By default, it is calculated from # 1 => 1.0
# @move_speed and has these values (assuming 40 fps): # 2 => 0.5
# 1 => 3.2 # 40 frames per tile # 3 => 0.25 # Walking speed
# 2 => 6.4 # 20 frames per tile # 4 => 0.125 # Running speed (2x walking speed)
# 3 => 12.8 # 10 frames per tile - walking speed # 5 => 0.1 # Cycling speed (1.25x running speed)
# 4 => 25.6 # 5 frames per tile - running speed (2x walking speed) # 6 => 0.05
# 5 => 32 # 4 frames per tile - cycling speed (1.25x running speed) @move_time = (val == 6) ? 0.05 : (val == 5) ? 0.1 : 2.0 / (2**val)
# 6 => 64 # 2 frames per tile
self.move_speed_real = (val == 6) ? 64 : (val == 5) ? 32 : (2**(val + 1)) * 0.8
end end
def move_speed_real # Takes the same values as move_speed above.
self.move_speed = @move_speed if !@move_speed_real def jump_speed=(val)
return @move_speed_real @jump_speed = val
@jump_time = (val == 6) ? 0.05 : (val == 5) ? 0.1 : 2.0 / (2**val)
end end
def move_speed_real=(val) # Returns time in seconds for one full cycle (4 frames) of an animating
@move_speed_real = val * 40.0 / Graphics.frame_rate # charset to show. Two frames are shown per movement across one tile.
end def pattern_update_speed
return @jump_time * 2 if jumping?
def jump_speed_real ret = @move_time * 2
self.jump_speed_real = (2**(3 + 1)) * 0.8 if !@jump_speed_real # 3 is walking speed ret *= 2 if @move_speed >= 5 # Cycling speed or faster; slower animation
return @jump_speed_real return ret
end
def jump_speed_real=(val)
@jump_speed_real = val * 40.0 / Graphics.frame_rate
end end
def move_frequency=(val) def move_frequency=(val)
return if val == @move_frequency return if val == @move_frequency
@move_frequency = val @move_frequency = val
# @move_frequency_real is the number of frames to wait between each action # Time in seconds to wait between each action in a move route (not forced).
# in a move route (not forced). Specifically, this is the number of frames # Specifically, this is the time to wait after the character stops moving
# to wait after the character stops moving because of the previous action. # because of the previous action.
# By default, it is calculated from @move_frequency and has these values # 1 => 4.75 seconds
# (assuming 40 fps): # 2 => 3.6 seconds
# 1 => 190 # 4.75 seconds # 3 => 2.55 seconds
# 2 => 144 # 3.6 seconds # 4 => 1.6 seconds
# 3 => 102 # 2.55 seconds # 5 => 0.75 seconds
# 4 => 64 # 1.6 seconds # 6 => 0 seconds, i.e. continuous movement
# 5 => 30 # 0.75 seconds @command_delay = (40 - (val * 2)) * (6 - val) / 40.0
# 6 => 0 # 0 seconds, i.e. continuous movement
self.move_frequency_real = (40 - (val * 2)) * (6 - val)
end
def move_frequency_real
self.move_frequency = @move_frequency if !@move_frequency_real
return @move_frequency_real
end
def move_frequency_real=(val)
@move_frequency_real = val * Graphics.frame_rate / 40.0
end end
def bob_height def bob_height
@@ -327,12 +312,8 @@ class Game_Character
def screen_y def screen_y
ret = screen_y_ground ret = screen_y_ground
if jumping? if jumping?
if @jump_count > 0 jump_progress = (@jump_fraction - 0.5).abs # 0.5 to 0 to 0.5
jump_fraction = ((@jump_count * jump_speed_real / Game_Map::REAL_RES_X) - 0.5).abs # 0.5 to 0 to 0.5 ret += @jump_peak * ((4 * (jump_progress**2)) - 1)
else
jump_fraction = ((@jump_distance_left / @jump_distance) - 0.5).abs # 0.5 to 0 to 0.5
end
ret += @jump_peak * ((4 * (jump_fraction**2)) - 1)
end end
ret += self.y_offset ret += self.y_offset
return ret return ret
@@ -361,7 +342,7 @@ class Game_Character
end end
def jumping? def jumping?
return (@jump_distance_left || 0) > 0 || @jump_count > 0 return !@jump_timer.nil?
end end
def straighten def straighten
@@ -437,11 +418,17 @@ class Game_Character
def move_type_custom def move_type_custom
return if jumping? || moving? return if jumping? || moving?
return if @move_route.list.size <= 1 # Empty move route
start_index = @move_route_index
done_one_command = false
while @move_route_index < @move_route.list.size while @move_route_index < @move_route.list.size
return if @move_route_index == start_index && done_one_command
done_one_command = true
command = @move_route.list[@move_route_index] command = @move_route.list[@move_route_index]
if command.code == 0 if command.code == 0
if @move_route.repeat if @move_route.repeat
@move_route_index = 0 @move_route_index = 0
command = @move_route.list[@move_route_index]
else else
if @move_route_forcing if @move_route_forcing
@move_route_forcing = false @move_route_forcing = false
@@ -450,9 +437,11 @@ class Game_Character
@original_move_route = nil @original_move_route = nil
end end
@stop_count = 0 @stop_count = 0
end
return return
end end
end
# The below move route commands wait for a frame (i.e. return) after
# executing them
if command.code <= 14 if command.code <= 14
case command.code case command.code
when 1 then move_down when 1 then move_down
@@ -473,14 +462,13 @@ class Game_Character
@move_route_index += 1 if @move_route.skippable || moving? || jumping? @move_route_index += 1 if @move_route.skippable || moving? || jumping?
return return
end end
if command.code == 15 # Wait # The below move route commands wait for a frame (i.e. return) after
# executing them
if command.code >= 15 && command.code <= 26
case command.code
when 15 # Wait
@wait_count = command.parameters[0] / 20.0 @wait_count = command.parameters[0] / 20.0
@wait_start = System.uptime @wait_start = System.uptime
@move_route_index += 1
return
end
if command.code >= 16 && command.code <= 26
case command.code
when 16 then turn_down when 16 then turn_down
when 17 then turn_left when 17 then turn_left
when 18 then turn_right when 18 then turn_right
@@ -496,6 +484,8 @@ class Game_Character
@move_route_index += 1 @move_route_index += 1
return return
end end
# The below move route commands don't wait for a frame (i.e. return) after
# executing them
if command.code >= 27 if command.code >= 27
case command.code case command.code
when 27 when 27
@@ -551,8 +541,11 @@ class Game_Character
turn_generic(dir) if turn_enabled turn_generic(dir) if turn_enabled
if can_move_in_direction?(dir) if can_move_in_direction?(dir)
turn_generic(dir) turn_generic(dir)
@move_initial_x = @x
@move_initial_y = @y
@x += (dir == 4) ? -1 : (dir == 6) ? 1 : 0 @x += (dir == 4) ? -1 : (dir == 6) ? 1 : 0
@y += (dir == 8) ? -1 : (dir == 2) ? 1 : 0 @y += (dir == 8) ? -1 : (dir == 2) ? 1 : 0
@move_timer = 0.0
increase_steps increase_steps
else else
check_event_trigger_touch(dir) check_event_trigger_touch(dir)
@@ -580,8 +573,11 @@ class Game_Character
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction) @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end end
if can_move_in_direction?(7) if can_move_in_direction?(7)
@move_initial_x = @x
@move_initial_y = @y
@x -= 1 @x -= 1
@y -= 1 @y -= 1
@move_timer = 0.0
increase_steps increase_steps
end end
end end
@@ -591,8 +587,11 @@ class Game_Character
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction) @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end end
if can_move_in_direction?(9) if can_move_in_direction?(9)
@move_initial_x = @x
@move_initial_y = @y
@x += 1 @x += 1
@y -= 1 @y -= 1
@move_timer = 0.0
increase_steps increase_steps
end end
end end
@@ -602,8 +601,11 @@ class Game_Character
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction) @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end end
if can_move_in_direction?(1) if can_move_in_direction?(1)
@move_initial_x = @x
@move_initial_y = @y
@x -= 1 @x -= 1
@y += 1 @y += 1
@move_timer = 0.0
increase_steps increase_steps
end end
end end
@@ -613,8 +615,11 @@ class Game_Character
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction) @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end end
if can_move_in_direction?(3) if can_move_in_direction?(3)
@move_initial_x = @x
@move_initial_y = @y
@x += 1 @x += 1
@y += 1 @y += 1
@move_timer = 0.0
increase_steps increase_steps
end end
end end
@@ -753,19 +758,16 @@ class Game_Character
end end
each_occupied_tile { |i, j| return if !passable?(i + x_plus, j + y_plus, 0) } each_occupied_tile { |i, j| return if !passable?(i + x_plus, j + y_plus, 0) }
end end
@jump_initial_x = @x
@jump_initial_y = @y
@x = @x + x_plus @x = @x + x_plus
@y = @y + y_plus @y = @y + y_plus
real_distance = Math.sqrt((x_plus * x_plus) + (y_plus * y_plus)) @jump_timer = 0.0
real_distance = Math.sqrt(x_plus**2 + y_plus**2)
distance = [1, real_distance].max distance = [1, real_distance].max
@jump_peak = distance * Game_Map::TILE_HEIGHT * 3 / 8 # 3/4 of tile for ledge jumping @jump_peak = distance * Game_Map::TILE_HEIGHT * 3 / 8 # 3/4 of tile for ledge jumping
@jump_distance = [x_plus.abs * Game_Map::REAL_RES_X, y_plus.abs * Game_Map::REAL_RES_Y].max @jump_distance = [x_plus.abs * Game_Map::REAL_RES_X, y_plus.abs * Game_Map::REAL_RES_Y].max
@jump_distance_left = 1 # Just needs to be non-zero @jumping_on_spot = (real_distance == 0)
if real_distance > 0 # Jumping to somewhere else
@jump_count = 0
else # Jumping on the spot
@jump_speed_real = nil # Reset jump speed
@jump_count = Game_Map::REAL_RES_X / jump_speed_real # Number of frames to jump one tile
end
increase_steps increase_steps
end end
@@ -874,16 +876,20 @@ class Game_Character
# Updating # Updating
#============================================================================= #=============================================================================
def update def update
return if $game_temp.in_menu
time_now = System.uptime
@last_update_time = time_now if !@last_update_time || @last_update_time > time_now
@delta_t = time_now - @last_update_time
@last_update_time = time_now
return if @delta_t > 0.25 # Was in a menu; delay movement
@moved_last_frame = @moved_this_frame @moved_last_frame = @moved_this_frame
@stopped_last_frame = @stopped_this_frame @stopped_last_frame = @stopped_this_frame
@moved_this_frame = false @moved_this_frame = false
@stopped_this_frame = false @stopped_this_frame = false
if !$game_temp.in_menu
# Update command # Update command
update_command update_command
# Update movement # Update movement
(moving? || jumping?) ? update_move : update_stop (moving? || jumping?) ? update_move : update_stop
end
# Update animation # Update animation
update_pattern update_pattern
end end
@@ -902,15 +908,7 @@ class Game_Character
end end
def update_command_new def update_command_new
# @stop_count is the number of frames since the last movement finished. if @stop_count >= @command_delay
# @move_frequency has these values:
# 1 => @stop_count > 190 # 4.75 seconds
# 2 => @stop_count > 144 # 3.6 seconds
# 3 => @stop_count > 102 # 2.55 seconds
# 4 => @stop_count > 64 # 1.6 seconds
# 5 => @stop_count > 30 # 0.75 seconds
# 6 => @stop_count > 0 # 0 seconds
if @stop_count >= self.move_frequency_real
case @move_type case @move_type
when 1 then move_type_random when 1 then move_type_random
when 2 then move_type_toward_player when 2 then move_type_toward_player
@@ -920,29 +918,48 @@ class Game_Character
end end
def update_move def update_move
# Move the character (the 0.1 catches rounding errors) if @move_timer
distance = (jumping?) ? jump_speed_real : move_speed_real @move_timer += @delta_t
dest_x = @x * Game_Map::REAL_RES_X # Move horizontally
dest_y = @y * Game_Map::REAL_RES_Y if @x != @move_initial_x
if @real_x < dest_x dist = (@move_initial_x - @x).abs
@real_x += distance @real_x = lerp(@move_initial_x, @x, @move_time * dist, @move_timer) * Game_Map::REAL_RES_X
@real_x = dest_x if @real_x > dest_x - 0.1
else
@real_x -= distance
@real_x = dest_x if @real_x < dest_x + 0.1
end end
if @real_y < dest_y # Move vertically
@real_y += distance if @y != @move_initial_y
@real_y = dest_y if @real_y > dest_y - 0.1 dist = (@move_initial_y - @y).abs
else @real_y = lerp(@move_initial_y, @y, @move_time * dist, @move_timer) * Game_Map::REAL_RES_Y
@real_y -= distance
@real_y = dest_y if @real_y < dest_y + 0.1
end end
# Refresh how far is left to travel in a jump elsif @jump_timer
was_jumping = jumping? self.jump_speed = 3 if !@jump_time
if was_jumping @jump_timer += @delta_t
@jump_count -= 1 if @jump_count > 0 # For stationary jumps only dist = [(@x - @jump_initial_x).abs, (@y - @jump_initial_y).abs].max
@jump_distance_left = [(dest_x - @real_x).abs, (dest_y - @real_y).abs].max dist = 1 if dist == 0 # Jumping on spot
# Move horizontally
if @x != @jump_initial_x
@real_x = lerp(@jump_initial_x, @x, @jump_time * dist, @jump_timer) * Game_Map::REAL_RES_X
end
# Move vertically
if @y != @jump_initial_y
@real_y = lerp(@jump_initial_y, @y, @jump_time * dist, @jump_timer) * Game_Map::REAL_RES_Y
end
# Calculate how far through the jump we are (from 0 to 1)
@jump_fraction = @jump_timer / (@jump_time * dist)
end
# Snap to end position if close enough
@real_x = @x * Game_Map::REAL_RES_X if (@real_x - (@x * Game_Map::REAL_RES_X)).abs < Game_Map::X_SUBPIXELS / 2
@real_y = @y * Game_Map::REAL_RES_Y if (@real_y - (@y * Game_Map::REAL_RES_Y)).abs < Game_Map::Y_SUBPIXELS / 2
# End of move
if !moving?
@move_timer = nil
end
# End of jump
if jumping? && @jump_fraction >= 1
@jump_timer = nil
@jump_peak = 0
@jump_distance = 0
@jump_fraction = 0
@jumping_on_spot = false
end end
# End of a step, so perform events that happen at this time # End of a step, so perform events that happen at this time
if !jumping? && !moving? if !jumping? && !moving?
@@ -953,18 +970,18 @@ class Game_Character
calculate_bush_depth calculate_bush_depth
end end
# Increment animation counter # Increment animation counter
@anime_count += 1 if @walk_anime || @step_anime @anime_count += @delta_t if @walk_anime || @step_anime
@moved_this_frame = true @moved_this_frame = true
end end
def update_stop def update_stop
@anime_count += 1 if @step_anime @anime_count += @delta_t if @step_anime
@stop_count += 1 if !@starting && !lock? @stop_count += @delta_t if !@starting && !lock?
end end
def update_pattern def update_pattern
return if @lock_pattern return if @lock_pattern
# return if @jump_count > 0 # Don't animate if jumping on the spot # return if @jumping_on_spot # Don't animate if jumping on the spot
# Character has stopped moving, return to original pattern # Character has stopped moving, return to original pattern
if @moved_last_frame && !@moved_this_frame && !@step_anime if @moved_last_frame && !@moved_this_frame && !@step_anime
@pattern = @original_pattern @pattern = @original_pattern
@@ -980,12 +997,10 @@ class Game_Character
# Calculate how many frames each pattern should display for, i.e. the time # Calculate how many frames each pattern should display for, i.e. the time
# it takes to move half a tile (or a whole tile if cycling). We assume the # it takes to move half a tile (or a whole tile if cycling). We assume the
# game uses square tiles. # game uses square tiles.
real_speed = (jumping?) ? jump_speed_real : move_speed_real pattern_time = pattern_update_speed / 4 # 4 frames per cycle in a charset
frames_per_pattern = Game_Map::REAL_RES_X / (real_speed * 2.0) return if @anime_count < pattern_time
frames_per_pattern *= 2 if move_speed >= 5 # Cycling speed or faster
return if @anime_count < frames_per_pattern
# Advance to the next animation frame # Advance to the next animation frame
@pattern = (@pattern + 1) % 4 @pattern = (@pattern + 1) % 4
@anime_count -= frames_per_pattern @anime_count -= pattern_time
end end
end end

View File

@@ -48,6 +48,8 @@ class Game_Player < Game_Character
return $PokemonGlobal.followers.length == 0 return $PokemonGlobal.followers.length == 0
end end
#-----------------------------------------------------------------------------
def can_run? def can_run?
return @move_speed > 3 if @move_route_forcing return @move_speed > 3 if @move_route_forcing
return false if $game_temp.in_menu || $game_temp.in_battle || return false if $game_temp.in_menu || $game_temp.in_battle ||
@@ -110,6 +112,8 @@ class Game_Player < Game_Character
@character_name = new_charset if new_charset @character_name = new_charset if new_charset
end end
#-----------------------------------------------------------------------------
def bump_into_object def bump_into_object
return if @bump_se && @bump_se > 0 return if @bump_se && @bump_se > 0
pbSEPlay("Player bump") if !@move_route_forcing pbSEPlay("Player bump") if !@move_route_forcing
@@ -146,8 +150,11 @@ class Game_Player < Game_Character
# General movement # General movement
turn_generic(dir, true) turn_generic(dir, true)
if !$game_temp.encounter_triggered if !$game_temp.encounter_triggered
@move_initial_x = @x
@move_initial_y = @y
@x += x_offset @x += x_offset
@y += y_offset @y += y_offset
@move_timer = 0.0
add_move_distance_to_stats(x_offset.abs + y_offset.abs) add_move_distance_to_stats(x_offset.abs + y_offset.abs)
increase_steps increase_steps
end end
@@ -174,49 +181,7 @@ class Game_Player < Game_Character
add_move_distance_to_stats(x_plus.abs + y_plus.abs) if @x != old_x || @y != old_y add_move_distance_to_stats(x_plus.abs + y_plus.abs) if @x != old_x || @y != old_y
end end
def pbTriggeredTrainerEvents(triggers, checkIfRunning = true, trainer_only = false) #-----------------------------------------------------------------------------
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/trainer\((\d+)\)/i] && (trainer_only || !event.name[/sight\((\d+)\)/i])
distance = $~[1].to_i
next if !pbEventCanReachPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbTriggeredCounterEvents(triggers, checkIfRunning = true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventFacesPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbCheckEventTriggerAfterTurning; end
def pbCheckEventTriggerFromDistance(triggers)
ret = pbTriggeredTrainerEvents(triggers)
ret.concat(pbTriggeredCounterEvents(triggers))
return false if ret.length == 0
ret.each do |event|
event.start
end
return true
end
def pbTerrainTag(countBridge = false) def pbTerrainTag(countBridge = false)
return $map_factory.getTerrainTagFromCoords(self.map.map_id, @x, @y, countBridge) if $map_factory return $map_factory.getTerrainTagFromCoords(self.map.map_id, @x, @y, countBridge) if $map_factory
@@ -303,6 +268,52 @@ class Game_Player < Game_Character
@blend_type = 0 @blend_type = 0
end end
#-----------------------------------------------------------------------------
def pbTriggeredTrainerEvents(triggers, checkIfRunning = true, trainer_only = false)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/trainer\((\d+)\)/i] && (trainer_only || !event.name[/sight\((\d+)\)/i])
distance = $~[1].to_i
next if !pbEventCanReachPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbTriggeredCounterEvents(triggers, checkIfRunning = true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventFacesPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbCheckEventTriggerAfterTurning; end
def pbCheckEventTriggerFromDistance(triggers)
ret = pbTriggeredTrainerEvents(triggers)
ret.concat(pbTriggeredCounterEvents(triggers))
return false if ret.length == 0
ret.each do |event|
event.start
end
return true
end
# Trigger event(s) at the same coordinates as self with the appropriate # Trigger event(s) at the same coordinates as self with the appropriate
# trigger(s) that can be triggered # trigger(s) that can be triggered
def check_event_trigger_here(triggers) def check_event_trigger_here(triggers)
@@ -387,6 +398,8 @@ class Game_Player < Game_Character
return result return result
end end
#-----------------------------------------------------------------------------
def update def update
last_real_x = @real_x last_real_x = @real_x
last_real_y = @real_y last_real_y = @real_y

View File

@@ -68,11 +68,12 @@ class Game_Follower < Game_Event
# Can't walk over the middle tile, but can walk over the end tile; jump over # Can't walk over the middle tile, but can walk over the end tile; jump over
if location_passable?(self.x, self.y, direction) if location_passable?(self.x, self.y, direction)
if leader.jumping? if leader.jumping?
@jump_speed_real = leader.jump_speed_real self.jump_speed = leader.jump_speed || 3
else else
# This is doubled because self has to jump 2 tiles in the time it self.jump_speed = leader.move_speed || 3
# takes the leader to move one tile. # This is halved because self has to jump 2 tiles in the time it takes
@jump_speed_real = leader.move_speed_real * 2 # the leader to move one tile
@jump_time /= 2
end end
jump(delta_x, delta_y) jump(delta_x, delta_y)
else else
@@ -105,6 +106,21 @@ class Game_Follower < Game_Event
end end
end end
# Ceases all movement immediately. Used when the leader wants to move another
# tile but self hasn't quite finished its previous movement yet.
def end_movement
@x = x % self.map.width
@y = y % self.map.height
@real_x = @x * Game_Map::REAL_RES_X
@real_y = @y * Game_Map::REAL_RES_Y
@move_timer = nil
@jump_timer = nil
@jump_peak = 0
@jump_distance = 0
@jump_fraction = 0
@jumping_on_spot = false
end
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def turn_towards_leader(leader) def turn_towards_leader(leader)
@@ -113,6 +129,7 @@ class Game_Follower < Game_Event
def follow_leader(leader, instant = false, leaderIsTrueLeader = true) def follow_leader(leader, instant = false, leaderIsTrueLeader = true)
return if @move_route_forcing return if @move_route_forcing
end_movement
maps_connected = $map_factory.areConnected?(leader.map.map_id, self.map.map_id) maps_connected = $map_factory.areConnected?(leader.map.map_id, self.map.map_id)
target = nil target = nil
# Get the target tile that self wants to move to # Get the target tile that self wants to move to

View File

@@ -240,6 +240,7 @@ class Game_FollowerFactory
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
def update def update
return if $game_temp.in_menu
followers = $PokemonGlobal.followers followers = $PokemonGlobal.followers
return if followers.length == 0 return if followers.length == 0
# Update all followers # Update all followers

View File

@@ -18,7 +18,7 @@ class Sprite_Timer
def update def update
return if disposed? return if disposed?
if $game_system.timer_working if $game_system.timer_start
@timer.visible = true if @timer @timer.visible = true if @timer
if !@timer if !@timer
@timer = Window_AdvancedTextPokemon.newWithSize("", Graphics.width - 120, 0, 120, 64) @timer = Window_AdvancedTextPokemon.newWithSize("", Graphics.width - 120, 0, 120, 64)
@@ -27,7 +27,7 @@ class Sprite_Timer
@timer.viewport = @viewport @timer.viewport = @viewport
@timer.z = 99998 @timer.z = 99998
end end
curtime = $game_system.timer / Graphics.frame_rate curtime = $game_system.timer
curtime = 0 if curtime < 0 curtime = 0 if curtime < 0
if curtime != @total_sec if curtime != @total_sec
# Calculate total number of seconds # Calculate total number of seconds

View File

@@ -22,7 +22,7 @@ module Graphics
duration = 0 duration = 0
filename = "" filename = ""
end end
duration *= Graphics.frame_rate / 20 # For default fade-in animation duration *= Graphics.frame_rate / 20 # For default fade-in animation, must be in frames
begin begin
transition_KGC_SpecialTransition(duration, filename, vague) transition_KGC_SpecialTransition(duration, filename, vague)
rescue Exception rescue Exception

View File

@@ -98,8 +98,6 @@ class Battle::Scene
# Update other graphics # Update other graphics
@sprites["battle_bg"].update if @sprites["battle_bg"].respond_to?("update") @sprites["battle_bg"].update if @sprites["battle_bg"].respond_to?("update")
Graphics.update Graphics.update
@frameCounter += 1
@frameCounter = @frameCounter % (Graphics.frame_rate * 12 / 20)
end end
def pbInputUpdate def pbInputUpdate
@@ -114,9 +112,9 @@ class Battle::Scene
cw&.update cw&.update
@battle.battlers.each_with_index do |b, i| @battle.battlers.each_with_index do |b, i|
next if !b next if !b
@sprites["dataBox_#{i}"]&.update(@frameCounter) @sprites["dataBox_#{i}"]&.update
@sprites["pokemon_#{i}"]&.update(@frameCounter) @sprites["pokemon_#{i}"]&.update
@sprites["shadow_#{i}"]&.update(@frameCounter) @sprites["shadow_#{i}"]&.update
end end
end end

View File

@@ -8,7 +8,6 @@ class Battle::Scene
@aborted = false @aborted = false
@battleEnd = false @battleEnd = false
@animations = [] @animations = []
@frameCounter = 0
end end
# Called whenever the battle begins. # Called whenever the battle begins.

View File

@@ -225,8 +225,8 @@ class Battle::Scene
elsif battler.hp < oldHP elsif battler.hp < oldHP
pbCommonAnimation("HealthDown", battler) if showAnim && @battle.showAnims pbCommonAnimation("HealthDown", battler) if showAnim && @battle.showAnims
end end
@sprites["dataBox_#{battler.index}"].animateHP(oldHP, battler.hp, battler.totalhp) @sprites["dataBox_#{battler.index}"].animate_hp(oldHP, battler.hp)
while @sprites["dataBox_#{battler.index}"].animatingHP while @sprites["dataBox_#{battler.index}"].animating_hp?
pbUpdate pbUpdate
end end
end end
@@ -253,7 +253,7 @@ class Battle::Scene
targets.each do |t| targets.each do |t|
anim = Animation::BattlerDamage.new(@sprites, @viewport, t[0].index, t[2]) anim = Animation::BattlerDamage.new(@sprites, @viewport, t[0].index, t[2])
damageAnims.push(anim) 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 end
# Update loop # Update loop
loop do loop do
@@ -261,7 +261,7 @@ class Battle::Scene
pbUpdate pbUpdate
allDone = true allDone = true
targets.each do |t| targets.each do |t|
next if !@sprites["dataBox_#{t[0].index}"].animatingHP next if !@sprites["dataBox_#{t[0].index}"].animating_hp?
allDone = false allDone = false
break break
end end
@@ -286,8 +286,8 @@ class Battle::Scene
endExpLevel = tempExp2 - startExp endExpLevel = tempExp2 - startExp
expRange = endExp - startExp expRange = endExp - startExp
dataBox = @sprites["dataBox_#{battler.index}"] dataBox = @sprites["dataBox_#{battler.index}"]
dataBox.animateExp(startExpLevel, endExpLevel, expRange) dataBox.animate_exp(startExpLevel, endExpLevel, expRange)
while dataBox.animatingExp while dataBox.animating_exp?
pbUpdate pbUpdate
end end
end end

View File

@@ -4,14 +4,20 @@
class Battle::Scene::PokemonDataBox < Sprite class Battle::Scene::PokemonDataBox < Sprite
attr_reader :battler attr_reader :battler
attr_accessor :selected attr_accessor :selected
attr_reader :animatingHP
attr_reader :animatingExp
# Time in seconds to fully fill the Exp bar (from empty). # Time in seconds to fully fill the Exp bar (from empty).
EXP_BAR_FILL_TIME = 1.75 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. # Maximum time in seconds to make a change to the HP bar.
HP_BAR_CHANGE_TIME = 1.0 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 STATUS_ICON_HEIGHT = 16
# Text colors
NAME_BASE_COLOR = Color.new(72, 72, 72) NAME_BASE_COLOR = Color.new(72, 72, 72)
NAME_SHADOW_COLOR = Color.new(184, 184, 184) NAME_SHADOW_COLOR = Color.new(184, 184, 184)
MALE_BASE_COLOR = Color.new(48, 96, 216) MALE_BASE_COLOR = Color.new(48, 96, 216)
@@ -27,12 +33,8 @@ class Battle::Scene::PokemonDataBox < Sprite
@spriteY = 0 @spriteY = 0
@spriteBaseX = 0 @spriteBaseX = 0
@selected = 0 @selected = 0
@frame = 0 @show_hp_numbers = false
@showHP = false # Specifically, show the HP numbers @show_exp_bar = false
@animatingHP = false
@showExp = false # Specifically, show the Exp bar
@animatingExp = false
@expFlash = 0
initializeDataBoxGraphic(sideSize) initializeDataBoxGraphic(sideSize)
initializeOtherGraphics(viewport) initializeOtherGraphics(viewport)
refresh refresh
@@ -45,8 +47,8 @@ class Battle::Scene::PokemonDataBox < Sprite
bgFilename = ["Graphics/UI/Battle/databox_normal", bgFilename = ["Graphics/UI/Battle/databox_normal",
"Graphics/UI/Battle/databox_normal_foe"][@battler.index % 2] "Graphics/UI/Battle/databox_normal_foe"][@battler.index % 2]
if onPlayerSide if onPlayerSide
@showHP = true @show_hp_numbers = true
@showExp = true @show_exp_bar = true
end end
else # Multiple Pokémon on side, use the thin dara box BG else # Multiple Pokémon on side, use the thin dara box BG
bgFilename = ["Graphics/UI/Battle/databox_thin", bgFilename = ["Graphics/UI/Battle/databox_thin",
@@ -143,7 +145,7 @@ class Battle::Scene::PokemonDataBox < Sprite
@sprites.each do |i| @sprites.each do |i|
i[1].visible = value if !i[1].disposed? i[1].visible = value if !i[1].disposed?
end end
@expBar.visible = (value && @showExp) @expBar.visible = (value && @show_exp_bar)
end end
def color=(value) def color=(value)
@@ -159,38 +161,46 @@ class Battle::Scene::PokemonDataBox < Sprite
end end
def hp def hp
return (@animatingHP) ? @currentHP : @battler.hp return (animating_hp?) ? @anim_hp_current : @battler.hp
end end
def exp_fraction def exp_fraction
return 0.0 if @rangeExp == 0 if animating_exp?
return (@animatingExp) ? @currentExp.to_f / @rangeExp : @battler.pokemon.exp_fraction return 0.0 if @anim_exp_range == 0
return @anim_exp_current.to_f / @anim_exp_range
end
return @battler.pokemon.exp_fraction
end end
def animateHP(oldHP, newHP, rangeHP) # NOTE: A change in HP takes the same amount of time to animate, no matter how
@currentHP = oldHP # big a change it is.
@endHP = newHP def animate_hp(old_val, new_val)
@rangeHP = rangeHP return if old_val == new_val
# NOTE: A change in HP takes the same amount of time to animate, no matter @anim_hp_start = old_val
# how big a change it is. @anim_hp_end = new_val
@hpIncPerFrame = (newHP - oldHP).abs / (HP_BAR_CHANGE_TIME * Graphics.frame_rate) @anim_hp_current = old_val
# minInc is the smallest amount that HP is allowed to change per frame. @anim_hp_timer_start = System.uptime
# 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
end end
def animateExp(oldExp, newExp, rangeExp) def animating_hp?
return if rangeExp == 0 return @anim_hp_timer_start != nil
@currentExp = oldExp end
@endExp = newExp
@rangeExp = rangeExp # NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME seconds
# NOTE: Filling the Exp bar from empty to full takes EXP_BAR_FILL_TIME # no matter what. Filling half of it takes half as long, etc.
# seconds no matter what. Filling half of it takes half as long, etc. def animate_exp(old_val, new_val, range)
@expIncPerFrame = rangeExp / (EXP_BAR_FILL_TIME * Graphics.frame_rate) return if old_val == new_val || range == 0 || !@show_exp_bar
@animatingExp = true @anim_exp_start = old_val
pbSEPlay("Pkmn exp gain") if @showExp @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 end
def pbDrawNumber(number, btmp, startX, startY, align = 0) def pbDrawNumber(number, btmp, startX, startY, align = 0)
@@ -284,15 +294,15 @@ class Battle::Scene::PokemonDataBox < Sprite
draw_shiny_icon draw_shiny_icon
draw_special_form_icon draw_special_form_icon
draw_owned_icon draw_owned_icon
refreshHP refresh_hp
refreshExp refresh_exp
end end
def refreshHP def refresh_hp
@hpNumbers.bitmap.clear @hpNumbers.bitmap.clear
return if !@battler.pokemon return if !@battler.pokemon
# Show HP numbers # Show HP numbers
if @showHP if @show_hp_numbers
pbDrawNumber(self.hp, @hpNumbers.bitmap, 54, 2, 1) pbDrawNumber(self.hp, @hpNumbers.bitmap, 54, 2, 1)
pbDrawNumber(-1, @hpNumbers.bitmap, 54, 2) # / char pbDrawNumber(-1, @hpNumbers.bitmap, 54, 2) # / char
pbDrawNumber(@battler.totalhp, @hpNumbers.bitmap, 70, 2) pbDrawNumber(@battler.totalhp, @hpNumbers.bitmap, 70, 2)
@@ -313,8 +323,8 @@ class Battle::Scene::PokemonDataBox < Sprite
@hpBar.src_rect.y = hpColor * @hpBarBitmap.height / 3 @hpBar.src_rect.y = hpColor * @hpBarBitmap.height / 3
end end
def refreshExp def refresh_exp
return if !@showExp return if !@show_exp_bar
w = exp_fraction * @expBarBitmap.width w = exp_fraction * @expBarBitmap.width
# NOTE: The line below snaps the bar's width to the nearest 2 pixels, to # 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. # 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 @expBar.src_rect.width = w
end end
def updateHPAnimation def update_hp_animation
return if !@animatingHP return if !animating_hp?
if @currentHP < @endHP # Gaining HP @anim_hp_current = lerp(@anim_hp_start, @anim_hp_end, HP_BAR_CHANGE_TIME,
@currentHP += @hpIncPerFrame @anim_hp_timer_start, System.uptime)
@currentHP = @endHP if @currentHP >= @endHP
elsif @currentHP > @endHP # Losing HP
@currentHP -= @hpIncPerFrame
@currentHP = @endHP if @currentHP <= @endHP
end
# Refresh the HP bar/numbers # Refresh the HP bar/numbers
refreshHP refresh_hp
@animatingHP = false if @currentHP == @endHP # 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 end
def updateExpAnimation def update_exp_animation
return if !@animatingExp return if !animating_exp?
if !@showExp # Not showing the Exp bar, no need to waste time animating it if !@show_exp_bar # Not showing the Exp bar, no need to waste time animating it
@currentExp = @endExp @anim_exp_timer_start = nil
@animatingExp = false
return return
end end
if @currentExp < @endExp # Gaining Exp duration = EXP_BAR_FILL_TIME * @anim_exp_duration_mult
@currentExp += @expIncPerFrame @anim_exp_current = lerp(@anim_exp_start, @anim_exp_end, duration,
@currentExp = @endExp if @currentExp >= @endExp @anim_exp_timer_start, System.uptime)
elsif @currentExp > @endExp # Losing Exp
@currentExp -= @expIncPerFrame
@currentExp = @endExp if @currentExp <= @endExp
end
# Refresh the Exp bar # Refresh the Exp bar
refreshExp refresh_exp
return if @currentExp != @endExp # Exp bar still has more to animate return if @anim_exp_current != @anim_exp_end # Exp bar still has more to animate
# Exp bar is completely filled, level up with a flash and sound effect # End the Exp bar filling animation
if @currentExp >= @rangeExp if @anim_exp_current >= @anim_exp_range
if @expFlash == 0 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
# Show the Exp full flash
@anim_exp_flash_timer_start = System.uptime
pbSEStop pbSEStop
@expFlash = Graphics.frame_rate / 5
pbSEPlay("Pkmn exp full") pbSEPlay("Pkmn exp full")
self.flash(Color.new(64, 200, 248, 192), @expFlash) 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| @sprites.each do |i|
i[1].flash(Color.new(64, 200, 248, 192), @expFlash) if !i[1].disposed? i[1].flash(Color.new(64, 200, 248, 192), flash_duration) if !i[1].disposed?
end end
else return
@expFlash -= 1
@animatingExp = false if @expFlash == 0
end end
else
pbSEStop
# Exp bar has finished filling, end animation
@animatingExp = false
end 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 end
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20 def update_positions
def updatePositions(frameCounter)
self.x = @spriteX self.x = @spriteX
self.y = @spriteY self.y = @spriteY
# Data box bobbing while Pokémon is selected # Data box bobbing while Pokémon is selected
if @selected == 1 || @selected == 2 # Choosing commands/targeted or damaged if (@selected == 1 || @selected == 2) && BOBBING_DURATION # Choosing commands/targeted
case (frameCounter / QUARTER_ANIM_PERIOD).floor 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 1 then self.y = @spriteY - 2
when 3 then self.y = @spriteY + 2 when 3 then self.y = @spriteY + 2
end end
end end
end end
def update(frameCounter = 0) def update
super() super
# Animate HP bar # Animate HP bar
updateHPAnimation update_hp_animation
# Animate Exp bar # Animate Exp bar
updateExpAnimation update_exp_animation
# Update coordinates of the data box # Update coordinates of the data box
updatePositions(frameCounter) update_positions
pbUpdateSpriteHash(@sprites) pbUpdateSpriteHash(@sprites)
end end
end end
@@ -502,6 +514,13 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
attr_accessor :selected attr_accessor :selected
attr_reader :sideSize 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) def initialize(viewport, sideSize, index, battleAnimations)
super(viewport) super(viewport)
@pkmn = nil @pkmn = nil
@@ -511,7 +530,6 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
# @selected: 0 = not selected, 1 = choosing action bobbing for this Pokémon, # @selected: 0 = not selected, 1 = choosing action bobbing for this Pokémon,
# 2 = flashing when targeted # 2 = flashing when targeted
@selected = 0 @selected = 0
@frame = 0
@updating = false @updating = false
@spriteX = 0 # Actual x coordinate @spriteX = 0 # Actual x coordinate
@spriteY = 0 # Actual y coordinate @spriteY = 0 # Actual y coordinate
@@ -588,10 +606,7 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
@pkmn&.play_cry @pkmn&.play_cry
end end
QUARTER_ANIM_PERIOD = Graphics.frame_rate * 3 / 20 def update
SIXTH_ANIM_PERIOD = Graphics.frame_rate * 2 / 20
def update(frameCounter = 0)
return if !@_iconBitmap return if !@_iconBitmap
@updating = true @updating = true
# Update bitmap # Update bitmap
@@ -599,8 +614,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
self.bitmap = @_iconBitmap.bitmap self.bitmap = @_iconBitmap.bitmap
# Pokémon sprite bobbing while Pokémon is selected # Pokémon sprite bobbing while Pokémon is selected
@spriteYExtra = 0 @spriteYExtra = 0
if @selected == 1 # When choosing commands for this Pokémon if @selected == 1 && COMMAND_BOBBING_DURATION # When choosing commands for this Pokémon
case (frameCounter / QUARTER_ANIM_PERIOD).floor 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 1 then @spriteYExtra = 2
when 3 then @spriteYExtra = -2 when 3 then @spriteYExtra = -2
end end
@@ -609,11 +626,10 @@ class Battle::Scene::BattlerSprite < RPG::Sprite
self.y = self.y self.y = self.y
self.visible = @spriteVisible self.visible = @spriteVisible
# Pokémon sprite blinking when targeted # Pokémon sprite blinking when targeted
if @selected == 2 && @spriteVisible if @selected == 2 && @spriteVisible && TARGET_BLINKING_DURATION
case (frameCounter / SIXTH_ANIM_PERIOD).floor blink_delta = System.uptime % TARGET_BLINKING_DURATION # 0-TARGET_BLINKING_DURATION
when 2, 5 then self.visible = false blink_frame = (3 * blink_delta / TARGET_BLINKING_DURATION).floor
else self.visible = true self.visible = (blink_frame != 0)
end
end end
@updating = false @updating = false
end end
@@ -673,7 +689,7 @@ class Battle::Scene::BattlerShadowSprite < RPG::Sprite
pbSetPosition pbSetPosition
end end
def update(frameCounter = 0) def update
return if !@_iconBitmap return if !@_iconBitmap
# Update bitmap # Update bitmap
@_iconBitmap.update @_iconBitmap.update

View File

@@ -85,10 +85,6 @@ class Battle::Scene::SafariDataBox < Sprite
textpos.push([_INTL("Left: {1}", @battle.ballCount), 30, 44, :left, base, shadow]) textpos.push([_INTL("Left: {1}", @battle.ballCount), 30, 44, :left, base, shadow])
pbDrawTextPositions(self.bitmap, textpos) pbDrawTextPositions(self.bitmap, textpos)
end end
def update(frameCounter = 0)
super()
end
end end
#=============================================================================== #===============================================================================

View File

@@ -49,7 +49,6 @@ EventHandlers.add(:on_frame_update, :low_battery_warning,
next if $game_temp.warned_low_battery || !pbBatteryLow? next if $game_temp.warned_low_battery || !pbBatteryLow?
next if $game_temp.in_menu || $game_temp.in_battle || $game_player.move_route_forcing || next if $game_temp.in_menu || $game_temp.in_battle || $game_player.move_route_forcing ||
$game_temp.message_window_showing || pbMapInterpreterRunning? $game_temp.message_window_showing || pbMapInterpreterRunning?
next if Time.now.sec != 0
$game_temp.warned_low_battery = true $game_temp.warned_low_battery = true
pbMessage(_INTL("The game has detected that the battery is low. You should save soon to avoid losing your progress.")) pbMessage(_INTL("The game has detected that the battery is low. You should save soon to avoid losing your progress."))
} }

View File

@@ -4,15 +4,17 @@
class ItemIconSprite < Sprite class ItemIconSprite < Sprite
attr_reader :item attr_reader :item
# Height in pixels the item's icon graphic must be for it to be animated by
# being a horizontal set of frames.
ANIM_ICON_SIZE = 48 ANIM_ICON_SIZE = 48
FRAMES_PER_CYCLE = Graphics.frame_rate # Time in seconds for one animation cycle of this item icon.
ANIMATION_DURATION = 1.0
def initialize(x, y, item, viewport = nil) def initialize(x, y, item, viewport = nil)
super(viewport) super(viewport)
@animbitmap = nil @animbitmap = nil
@animframe = 0 @frames_count = 1
@numframes = 1 @current_frame = 0
@frame = 0
self.x = x self.x = x
self.y = y self.y = y
@blankzero = false @blankzero = false
@@ -28,7 +30,7 @@ class ItemIconSprite < Sprite
def width def width
return 0 if !self.bitmap || self.bitmap.disposed? return 0 if !self.bitmap || self.bitmap.disposed?
return (@numframes == 1) ? self.bitmap.width : ANIM_ICON_SIZE return (@frames_count == 1) ? self.bitmap.width : ANIM_ICON_SIZE
end end
def height def height
@@ -76,34 +78,32 @@ class ItemIconSprite < Sprite
@animbitmap = AnimatedBitmap.new(GameData::Item.icon_filename(@item)) @animbitmap = AnimatedBitmap.new(GameData::Item.icon_filename(@item))
self.bitmap = @animbitmap.bitmap self.bitmap = @animbitmap.bitmap
if self.bitmap.height == ANIM_ICON_SIZE if self.bitmap.height == ANIM_ICON_SIZE
@numframes = [(self.bitmap.width / ANIM_ICON_SIZE).floor, 1].max @frames_count = [(self.bitmap.width / ANIM_ICON_SIZE).floor, 1].max
self.src_rect = Rect.new(0, 0, ANIM_ICON_SIZE, ANIM_ICON_SIZE) self.src_rect = Rect.new(0, 0, ANIM_ICON_SIZE, ANIM_ICON_SIZE)
else else
@numframes = 1 @frames_count = 1
self.src_rect = Rect.new(0, 0, self.bitmap.width, self.bitmap.height) self.src_rect = Rect.new(0, 0, self.bitmap.width, self.bitmap.height)
end end
@animframe = 0 @current_frame = 0
@frame = 0
else else
self.bitmap = nil self.bitmap = nil
end end
changeOrigin changeOrigin
end end
def update_frame
@current_frame = (@frames_count * (System.uptime % ANIMATION_DURATION) / ANIMATION_DURATION).floor
end
def update def update
@updating = true @updating = true
super super
if @animbitmap if @animbitmap
@animbitmap.update @animbitmap.update
self.bitmap = @animbitmap.bitmap self.bitmap = @animbitmap.bitmap
if @numframes > 1 if @frames_count > 1
frameskip = (FRAMES_PER_CYCLE / @numframes).floor update_frame
@frame = (@frame + 1) % FRAMES_PER_CYCLE self.src_rect.x = @current_frame * ANIM_ICON_SIZE
if @frame >= frameskip
@animframe = (@animframe + 1) % @numframes
self.src_rect.x = @animframe * ANIM_ICON_SIZE
@frame = 0
end
end end
end end
@updating = false @updating = false

View File

@@ -1,5 +1,5 @@
#=============================================================================== #===============================================================================
# Pokémon sprite (used out of battle) # Pokémon sprite (used out of battle).
#=============================================================================== #===============================================================================
class PokemonSprite < Sprite class PokemonSprite < Sprite
def initialize(viewport = nil) def initialize(viewport = nil)
@@ -78,20 +78,24 @@ class PokemonSprite < Sprite
end end
#=============================================================================== #===============================================================================
# Pokémon icon (for defined Pokémon) # Pokémon icon (for defined Pokémon).
#=============================================================================== #===============================================================================
class PokemonIconSprite < Sprite class PokemonIconSprite < Sprite
attr_accessor :selected attr_accessor :selected
attr_accessor :active attr_accessor :active
attr_reader :pokemon attr_reader :pokemon
# Time in seconds for one animation cycle of this Pokémon icon. It is doubled
# if the Pokémon is at 50% HP or lower, and doubled again if it is at 25% HP
# or lower. The icon doesn't animate at all if the Pokémon is fainted.
ANIMATION_DURATION = 0.25
def initialize(pokemon, viewport = nil) def initialize(pokemon, viewport = nil)
super(viewport) super(viewport)
@selected = false @selected = false
@active = false @active = false
@numFrames = 0 @frames_count = 0
@currentFrame = 0 @current_frame = 0
@counter = 0
self.pokemon = pokemon self.pokemon = pokemon
@logical_x = 0 # Actual x coordinate @logical_x = 0 # Actual x coordinate
@logical_y = 0 # Actual y coordinate @logical_y = 0 # Actual y coordinate
@@ -123,16 +127,15 @@ class PokemonIconSprite < Sprite
@animBitmap = nil @animBitmap = nil
if !@pokemon if !@pokemon
self.bitmap = nil self.bitmap = nil
@currentFrame = 0 @current_frame = 0
@counter = 0
return return
end end
@animBitmap = AnimatedBitmap.new(GameData::Species.icon_filename_from_pokemon(value)) @animBitmap = AnimatedBitmap.new(GameData::Species.icon_filename_from_pokemon(value))
self.bitmap = @animBitmap.bitmap self.bitmap = @animBitmap.bitmap
self.src_rect.width = @animBitmap.height self.src_rect.width = @animBitmap.height
self.src_rect.height = @animBitmap.height self.src_rect.height = @animBitmap.height
@numFrames = @animBitmap.width / @animBitmap.height @frames_count = @animBitmap.width / @animBitmap.height
@currentFrame = 0 if @currentFrame >= @numFrames @current_frame = 0 if @current_frame >= @frames_count
changeOrigin changeOrigin
end end
@@ -164,20 +167,18 @@ class PokemonIconSprite < Sprite
end end
end end
# How long to show each frame of the icon for def update_frame
def counterLimit if @pokemon.fainted?
return 0 if @pokemon.fainted? # Fainted - no animation @current_frame = 0
# ret is initially the time a whole animation cycle lasts. It is divided by return
# the number of frames in that cycle at the end.
ret = Graphics.frame_rate / 4 # Green HP - 0.25 seconds
if @pokemon.hp <= @pokemon.totalhp / 4 # Red HP - 1 second
ret *= 4
elsif @pokemon.hp <= @pokemon.totalhp / 2 # Yellow HP - 0.5 seconds
ret *= 2
end end
ret /= @numFrames duration = ANIMATION_DURATION
ret = 1 if ret < 1 if @pokemon.hp <= @pokemon.totalhp / 4 # Red HP - 1 second
return ret duration *= 4
elsif @pokemon.hp <= @pokemon.totalhp / 2 # Yellow HP - 0.5 seconds
duration *= 2
end
@current_frame = (@frames_count * (System.uptime % duration) / duration).floor
end end
def update def update
@@ -186,21 +187,12 @@ class PokemonIconSprite < Sprite
@animBitmap.update @animBitmap.update
self.bitmap = @animBitmap.bitmap self.bitmap = @animBitmap.bitmap
# Update animation # Update animation
cl = self.counterLimit update_frame
if cl == 0 self.src_rect.x = self.src_rect.width * @current_frame
@currentFrame = 0
else
@counter += 1
if @counter >= cl
@currentFrame = (@currentFrame + 1) % @numFrames
@counter = 0
end
end
self.src_rect.x = self.src_rect.width * @currentFrame
# Update "jumping" animation (used in party screen) # Update "jumping" animation (used in party screen)
if @selected if @selected
@adjusted_x = 4 @adjusted_x = 4
@adjusted_y = (@currentFrame >= @numFrames / 2) ? -2 : 6 @adjusted_y = (@current_frame >= @frames_count / 2) ? -2 : 6
else else
@adjusted_x = 0 @adjusted_x = 0
@adjusted_y = 0 @adjusted_y = 0
@@ -211,7 +203,7 @@ class PokemonIconSprite < Sprite
end end
#=============================================================================== #===============================================================================
# Pokémon icon (for species) # Pokémon icon (for species).
#=============================================================================== #===============================================================================
class PokemonSpeciesIconSprite < Sprite class PokemonSpeciesIconSprite < Sprite
attr_reader :species attr_reader :species
@@ -219,15 +211,17 @@ class PokemonSpeciesIconSprite < Sprite
attr_reader :form attr_reader :form
attr_reader :shiny attr_reader :shiny
# Time in seconds for one animation cycle of this Pokémon icon.
ANIMATION_DURATION = 0.25
def initialize(species, viewport = nil) def initialize(species, viewport = nil)
super(viewport) super(viewport)
@species = species @species = species
@gender = 0 @gender = 0
@form = 0 @form = 0
@shiny = 0 @shiny = 0
@numFrames = 0 @frames_count = 0
@currentFrame = 0 @current_frame = 0
@counter = 0
refresh refresh
end end
@@ -292,16 +286,6 @@ class PokemonSpeciesIconSprite < Sprite
end end
end end
# How long to show each frame of the icon for
def counterLimit
# ret is initially the time a whole animation cycle lasts. It is divided by
# the number of frames in that cycle at the end.
ret = Graphics.frame_rate / 4 # 0.25 seconds
ret /= @numFrames
ret = 1 if ret < 1
return ret
end
def refresh def refresh
@animBitmap&.dispose @animBitmap&.dispose
@animBitmap = nil @animBitmap = nil
@@ -311,22 +295,22 @@ class PokemonSpeciesIconSprite < Sprite
self.bitmap = @animBitmap.bitmap self.bitmap = @animBitmap.bitmap
self.src_rect.width = @animBitmap.height self.src_rect.width = @animBitmap.height
self.src_rect.height = @animBitmap.height self.src_rect.height = @animBitmap.height
@numFrames = @animBitmap.width / @animBitmap.height @frames_count = @animBitmap.width / @animBitmap.height
@currentFrame = 0 if @currentFrame >= @numFrames @current_frame = 0 if @current_frame >= @frames_count
changeOrigin changeOrigin
end end
def update_frame
@current_frame = (@frames_count * (System.uptime % ANIMATION_DURATION) / ANIMATION_DURATION).floor
end
def update def update
return if !@animBitmap return if !@animBitmap
super super
@animBitmap.update @animBitmap.update
self.bitmap = @animBitmap.bitmap self.bitmap = @animBitmap.bitmap
# Update animation # Update animation
@counter += 1 update_frame
if @counter >= self.counterLimit self.src_rect.x = self.src_rect.width * @current_frame
@currentFrame = (@currentFrame + 1) % @numFrames
@counter = 0
end
self.src_rect.x = self.src_rect.width * @currentFrame
end end
end end

View File

@@ -2,13 +2,23 @@
# Walking charset, for use in text entry screens and load game screen # Walking charset, for use in text entry screens and load game screen
#=============================================================================== #===============================================================================
class TrainerWalkingCharSprite < Sprite class TrainerWalkingCharSprite < Sprite
attr_accessor :anim_duration
# Default time in seconds for one animation cycle of a charset. The icon for a
# storage box is 0.4 instead (set manually).
ANIMATION_DURATION = 0.5
def initialize(charset, viewport = nil) def initialize(charset, viewport = nil)
super(viewport) super(viewport)
@animbitmap = nil @animbitmap = nil
self.charset = charset self.charset = charset
@animframe = 0 # Current pattern @current_frame = 0 # Current pattern
@frame = 0 # Frame counter @anim_duration = ANIMATION_DURATION
self.animspeed = 5 # Animation speed (frames per pattern) end
def dispose
@animbitmap&.dispose
super
end end
def charset=(value) def charset=(value)
@@ -38,13 +48,8 @@ class TrainerWalkingCharSprite < Sprite
end end
end end
def animspeed=(value) def update_frame
@frameskip = value * Graphics.frame_rate / 40 @current_frame = (4 * (System.uptime % @anim_duration) / @anim_duration).floor
end
def dispose
@animbitmap&.dispose
super
end end
def update def update
@@ -54,12 +59,9 @@ class TrainerWalkingCharSprite < Sprite
@animbitmap.update @animbitmap.update
self.bitmap = @animbitmap.bitmap self.bitmap = @animbitmap.bitmap
end end
@frame += 1 # Update animation
if @frame >= @frameskip update_frame
@animframe = (@animframe + 1) % 4 self.src_rect.x = self.src_rect.width * @current_frame
self.src_rect.x = @animframe * @animbitmap.bitmap.width / 4
@frame -= @frameskip
end
@updating = false @updating = false
end end
end end

View File

@@ -23,14 +23,6 @@ class SpriteMetafile
FLASHDURATION = 18 FLASHDURATION = 18
BITMAP = 19 BITMAP = 19
def length
return @metafile.length
end
def [](i)
return @metafile[i]
end
def initialize(viewport = nil) def initialize(viewport = nil)
@metafile = [] @metafile = []
@values = [ @values = [
@@ -44,11 +36,19 @@ class SpriteMetafile
] ]
end end
def dispose; end
def disposed? def disposed?
return false return false
end end
def dispose; end def [](i)
return @metafile[i]
end
def length
return @metafile.length
end
def flash(color, duration) def flash(color, duration)
if duration > 0 if duration > 0
@@ -252,7 +252,7 @@ class SpriteMetafilePlayer
end end
def update def update
if @playing return if !@playing
(@index...@metafile.length).each do |j| (@index...@metafile.length).each do |j|
@index = j + 1 @index = j + 1
break if @metafile[j][0] < 0 break if @metafile[j][0] < 0
@@ -281,7 +281,6 @@ class SpriteMetafilePlayer
end end
@playing = false if @index == @metafile.length @playing = false if @index == @metafile.length
end end
end
end end
#=============================================================================== #===============================================================================
@@ -420,36 +419,29 @@ class PokemonEvolutionScene
end end
end end
def pbUpdateNarrowScreen def pbUpdateNarrowScreen(timer_start)
halfResizeDiff = 8 * 20 / Graphics.frame_rate return if @bgviewport.rect.y >= 80
if @bgviewport.rect.y < 80 buffer = 80
@bgviewport.rect.height -= halfResizeDiff * 2 @bgviewport.rect.height = Graphics.height - lerp(0, 64 + (buffer * 2), 0.7, timer_start, System.uptime).to_i
if @bgviewport.rect.height < Graphics.height - 64 @bgviewport.rect.y = lerp(0, buffer, 0.5, timer_start + 0.2, System.uptime).to_i
@bgviewport.rect.y += halfResizeDiff
@sprites["background"].oy = @bgviewport.rect.y @sprites["background"].oy = @bgviewport.rect.y
end end
end
end
def pbUpdateExpandScreen def pbUpdateExpandScreen(timer_start)
halfResizeDiff = 8 * 20 / Graphics.frame_rate return if @bgviewport.rect.height >= Graphics.height
if @bgviewport.rect.y > 0 buffer = 80
@bgviewport.rect.y -= halfResizeDiff @bgviewport.rect.height = Graphics.height - lerp(64 + (buffer * 2), 0, 0.7, timer_start, System.uptime).to_i
@bgviewport.rect.y = lerp(buffer, 0, 0.5, timer_start, System.uptime).to_i
@sprites["background"].oy = @bgviewport.rect.y @sprites["background"].oy = @bgviewport.rect.y
end end
if @bgviewport.rect.height < Graphics.height
@bgviewport.rect.height += halfResizeDiff * 2
end
end
def pbFlashInOut(canceled, oldstate, oldstate2) def pbFlashInOut(canceled, oldstate, oldstate2)
tone = 0 timer_start = System.uptime
toneDiff = 20 * 20 / Graphics.frame_rate
loop do loop do
Graphics.update Graphics.update
pbUpdate(true) pbUpdate(true)
pbUpdateExpandScreen pbUpdateExpandScreen(timer_start)
tone += toneDiff tone = lerp(0, 255, 0.7, timer_start, System.uptime)
@viewport.tone.set(tone, tone, tone, 0) @viewport.tone.set(tone, tone, tone, 0)
break if tone >= 255 break if tone >= 255
end end
@@ -471,16 +463,18 @@ class PokemonEvolutionScene
@sprites["rsprite2"].zoom_y = 1.0 @sprites["rsprite2"].zoom_y = 1.0
@sprites["rsprite2"].color.alpha = 0 @sprites["rsprite2"].color.alpha = 0
end end
(Graphics.frame_rate / 4).times do timer_start = System.uptime
loop do
Graphics.update Graphics.update
pbUpdate(true) pbUpdate(true)
break if System.uptime - timer_start >= 0.25
end end
tone = 255 timer_start = System.uptime
toneDiff = 40 * 20 / Graphics.frame_rate
loop do loop do
Graphics.update Graphics.update
pbUpdate pbUpdate
tone -= toneDiff pbUpdateExpandScreen(timer_start)
tone = lerp(255, 0, 0.4, timer_start, System.uptime)
@viewport.tone.set(tone, tone, tone, 0) @viewport.tone.set(tone, tone, tone, 0)
break if tone <= 0 break if tone <= 0
end end
@@ -551,8 +545,9 @@ class PokemonEvolutionScene
pbMEPlay("Evolution start") pbMEPlay("Evolution start")
pbBGMPlay("Evolution") pbBGMPlay("Evolution")
canceled = false canceled = false
timer_start = System.uptime
loop do loop do
pbUpdateNarrowScreen pbUpdateNarrowScreen(timer_start)
metaplayer1.update metaplayer1.update
metaplayer2.update metaplayer2.update
Graphics.update Graphics.update
@@ -579,11 +574,13 @@ class PokemonEvolutionScene
def pbEvolutionSuccess def pbEvolutionSuccess
$stats.evolution_count += 1 $stats.evolution_count += 1
# Play cry of evolved species # Play cry of evolved species
frames = (GameData::Species.cry_length(@newspecies, @pokemon.form) * Graphics.frame_rate).ceil cry_time = GameData::Species.cry_length(@newspecies, @pokemon.form)
Pokemon.play_cry(@newspecies, @pokemon.form) Pokemon.play_cry(@newspecies, @pokemon.form)
(frames + 4).times do timer_start = System.uptime
loop do
Graphics.update Graphics.update
pbUpdate pbUpdate
break if System.uptime - timer_start >= cry_time
end end
pbBGMStop pbBGMStop
# Success jingle/message # Success jingle/message

View File

@@ -17,7 +17,7 @@ class PokemonLoadPanel < Sprite
@title = title @title = title
@isContinue = isContinue @isContinue = isContinue
@trainer = trainer @trainer = trainer
@totalsec = stats.play_time.to_i @totalsec = stats&.play_time.to_i || 0
@mapid = mapid @mapid = mapid
@selected = (index == 0) @selected = (index == 0)
@bgbitmap = AnimatedBitmap.new("Graphics/UI/Load/panels") @bgbitmap = AnimatedBitmap.new("Graphics/UI/Load/panels")

View File

@@ -5,7 +5,7 @@ class PokemonBoxIcon < IconSprite
def initialize(pokemon, viewport = nil) def initialize(pokemon, viewport = nil)
super(0, 0, viewport) super(0, 0, viewport)
@pokemon = pokemon @pokemon = pokemon
@release = Interpolator.new @release = SpriteInterpolator.new
@startRelease = false @startRelease = false
refresh refresh
end end
@@ -20,9 +20,9 @@ class PokemonBoxIcon < IconSprite
self.x += self.src_rect.width / 2 # 32 self.x += self.src_rect.width / 2 # 32
self.y += self.src_rect.height / 2 # 32 self.y += self.src_rect.height / 2 # 32
@release.tween(self, @release.tween(self,
[[Interpolator::ZOOM_X, 0], [[SpriteInterpolator::ZOOM_X, 0],
[Interpolator::ZOOM_Y, 0], [SpriteInterpolator::ZOOM_Y, 0],
[Interpolator::OPACITY, 0]], [SpriteInterpolator::OPACITY, 0]],
100) 100)
@startRelease = true @startRelease = true
end end
@@ -969,34 +969,32 @@ class PokemonStorageScene
end end
def pbChangeBackground(wp) def pbChangeBackground(wp)
duration = 0.2 # Time in seconds to fade out or fade in
@sprites["box"].refreshSprites = false @sprites["box"].refreshSprites = false
alpha = 0
Graphics.update Graphics.update
self.update self.update
timeTaken = Graphics.frame_rate * 4 / 10 # Fade old background to white
alphaDiff = (255.0 / timeTaken).ceil timer_start = System.uptime
timeTaken.times do loop do
alpha += alphaDiff alpha = lerp(0, 255, duration, timer_start, System.uptime)
Graphics.update
Input.update
@sprites["box"].color = Color.new(248, 248, 248, alpha) @sprites["box"].color = Color.new(248, 248, 248, alpha)
Graphics.update
self.update self.update
break if alpha >= 255
end end
# Fade in new background from white
@sprites["box"].refreshBox = true @sprites["box"].refreshBox = true
@storage[@storage.currentBox].background = wp @storage[@storage.currentBox].background = wp
(Graphics.frame_rate / 10).times do timer_start = System.uptime
Graphics.update loop do
Input.update alpha = lerp(255, 0, duration, timer_start, System.uptime)
self.update
end
timeTaken.times do
alpha -= alphaDiff
Graphics.update
Input.update
@sprites["box"].color = Color.new(248, 248, 248, alpha) @sprites["box"].color = Color.new(248, 248, 248, alpha)
Graphics.update
self.update self.update
break if alpha <= 0
end end
@sprites["box"].refreshSprites = true @sprites["box"].refreshSprites = true
Input.update
end end
def pbSwitchBoxToRight(newbox) def pbSwitchBoxToRight(newbox)

View File

@@ -168,7 +168,7 @@ class PokemonEntryScene
when 4 # Storage box when 4 # Storage box
@sprites["subject"] = TrainerWalkingCharSprite.new(nil, @viewport) @sprites["subject"] = TrainerWalkingCharSprite.new(nil, @viewport)
@sprites["subject"].altcharset = "Graphics/UI/Naming/icon_storage" @sprites["subject"].altcharset = "Graphics/UI/Naming/icon_storage"
@sprites["subject"].animspeed = 4 @sprites["subject"].anim_duration = 0.4
charwidth = @sprites["subject"].bitmap.width charwidth = @sprites["subject"].bitmap.width
charheight = @sprites["subject"].bitmap.height charheight = @sprites["subject"].bitmap.height
@sprites["subject"].x = 88 - (charwidth / 8) @sprites["subject"].x = 88 - (charwidth / 8)
@@ -449,7 +449,7 @@ class PokemonEntryScene2
when 4 # Storage box when 4 # Storage box
@sprites["subject"] = TrainerWalkingCharSprite.new(nil, @viewport) @sprites["subject"] = TrainerWalkingCharSprite.new(nil, @viewport)
@sprites["subject"].altcharset = "Graphics/UI/Naming/icon_storage" @sprites["subject"].altcharset = "Graphics/UI/Naming/icon_storage"
@sprites["subject"].animspeed = 4 @sprites["subject"].anim_duration = 0.4
charwidth = @sprites["subject"].bitmap.width charwidth = @sprites["subject"].bitmap.width
charheight = @sprites["subject"].bitmap.height charheight = @sprites["subject"].bitmap.height
@sprites["subject"].x = 88 - (charwidth / 8) @sprites["subject"].x = 88 - (charwidth / 8)

View File

@@ -169,7 +169,6 @@ class SlotMachineScene
end end
end end
@sprites["payout"].score = payout @sprites["payout"].score = payout
frame = 0
if payout > 0 || @replay if payout > 0 || @replay
if bonus > 0 if bonus > 0
pbMEPlay("Slots big win") pbMEPlay("Slots big win")
@@ -177,30 +176,31 @@ class SlotMachineScene
pbMEPlay("Slots win") pbMEPlay("Slots win")
end end
# Show winning animation # Show winning animation
timePerFrame = Graphics.frame_rate / 8 timer_start = System.uptime
until frame == Graphics.frame_rate * 3 loop do
Graphics.update frame = ((System.uptime - timer_start) / 0.125).to_i
Input.update
update
@sprites["window2"].bitmap&.clear @sprites["window2"].bitmap&.clear
@sprites["window1"].setBitmap("Graphics/UI/Slot Machine/win") @sprites["window1"].setBitmap("Graphics/UI/Slot Machine/win")
@sprites["window1"].src_rect.set(152 * ((frame / timePerFrame) % 4), 0, 152, 208) @sprites["window1"].src_rect.set(152 * (frame % 4), 0, 152, 208)
if bonus > 0 if bonus > 0
@sprites["window2"].setBitmap("Graphics/UI/Slot Machine/bonus") @sprites["window2"].setBitmap("Graphics/UI/Slot Machine/bonus")
@sprites["window2"].src_rect.set(152 * (bonus - 1), 0, 152, 208) @sprites["window2"].src_rect.set(152 * (bonus - 1), 0, 152, 208)
end end
@sprites["light1"].visible = true @sprites["light1"].visible = true
@sprites["light1"].src_rect.set(0, 26 * ((frame / timePerFrame) % 4), 96, 26) @sprites["light1"].src_rect.set(0, 26 * (frame % 4), 96, 26)
@sprites["light2"].visible = true @sprites["light2"].visible = true
@sprites["light2"].src_rect.set(0, 26 * ((frame / timePerFrame) % 4), 96, 26) @sprites["light2"].src_rect.set(0, 26 * (frame % 4), 96, 26)
(1..5).each do |i| (1..5).each do |i|
if wonRow[i - 1] if wonRow[i - 1]
@sprites["row#{i}"].visible = (frame / timePerFrame).even? @sprites["row#{i}"].visible = frame.even?
else else
@sprites["row#{i}"].visible = false @sprites["row#{i}"].visible = false
end end
end end
frame += 1 Graphics.update
Input.update
update
break if System.uptime - timer_start >= 3.0
end end
@sprites["light1"].visible = false @sprites["light1"].visible = false
@sprites["light2"].visible = false @sprites["light2"].visible = false
@@ -218,22 +218,25 @@ class SlotMachineScene
@sprites["payout"].score = 0 @sprites["payout"].score = 0
end end
end end
(Graphics.frame_rate / 2).times do timer_start = System.uptime
loop do
Graphics.update Graphics.update
Input.update Input.update
update update
break if System.uptime - timer_start >= 0.5
end end
else else
# Show losing animation # Show losing animation
timePerFrame = Graphics.frame_rate / 4 timer_start = System.uptime
until frame == Graphics.frame_rate * 2 loop do
frame = ((System.uptime - timer_start) / 0.25).to_i
@sprites["window2"].bitmap&.clear
@sprites["window1"].setBitmap("Graphics/UI/Slot Machine/lose")
@sprites["window1"].src_rect.set(152 * (frame % 2), 0, 152, 208)
Graphics.update Graphics.update
Input.update Input.update
update update
@sprites["window2"].bitmap&.clear break if System.uptime - timer_start >= 2.0
@sprites["window1"].setBitmap("Graphics/UI/Slot Machine/lose")
@sprites["window1"].src_rect.set(152 * ((frame / timePerFrame) % 2), 0, 152, 208)
frame += 1
end end
end end
@wager = 0 @wager = 0
@@ -278,9 +281,6 @@ class SlotMachineScene
end end
def pbMain def pbMain
frame = 0
spinFrameTime = Graphics.frame_rate / 4
insertFrameTime = Graphics.frame_rate * 4 / 10
loop do loop do
Graphics.update Graphics.update
Input.update Input.update
@@ -295,7 +295,13 @@ class SlotMachineScene
break break
elsif @gameRunning # Reels are spinning elsif @gameRunning # Reels are spinning
@sprites["window1"].setBitmap("Graphics/UI/Slot Machine/stop") @sprites["window1"].setBitmap("Graphics/UI/Slot Machine/stop")
@sprites["window1"].src_rect.set(152 * ((frame / spinFrameTime) % 4), 0, 152, 208) timer_start = System.uptime
loop do
frame = ((System.uptime - timer_start) / 0.25).to_i
@sprites["window1"].src_rect.set(152 * (frame % 4), 0, 152, 208)
Graphics.update
Input.update
update
if Input.trigger?(Input::USE) if Input.trigger?(Input::USE)
pbSEPlay("Slots stop") pbSEPlay("Slots stop")
if @sprites["reel1"].spinning if @sprites["reel1"].spinning
@@ -313,6 +319,8 @@ class SlotMachineScene
@gameEnd = true @gameEnd = true
@gameRunning = false @gameRunning = false
end end
break if !@gameRunning
end
elsif @gameEnd # Reels have been stopped elsif @gameEnd # Reels have been stopped
pbPayout pbPayout
# Reset graphics # Reset graphics
@@ -325,11 +333,17 @@ class SlotMachineScene
@gameEnd = false @gameEnd = false
else # Awaiting coins for the next spin else # Awaiting coins for the next spin
@sprites["window1"].setBitmap("Graphics/UI/Slot Machine/insert") @sprites["window1"].setBitmap("Graphics/UI/Slot Machine/insert")
@sprites["window1"].src_rect.set(152 * ((frame / insertFrameTime) % 2), 0, 152, 208) timer_start = System.uptime
loop do
frame = ((System.uptime - timer_start) / 0.4).to_i
@sprites["window1"].src_rect.set(152 * (frame % 2), 0, 152, 208)
if @wager > 0 if @wager > 0
@sprites["window2"].setBitmap("Graphics/UI/Slot Machine/press") @sprites["window2"].setBitmap("Graphics/UI/Slot Machine/press")
@sprites["window2"].src_rect.set(152 * ((frame / insertFrameTime) % 2), 0, 152, 208) @sprites["window2"].src_rect.set(152 * (frame % 2), 0, 152, 208)
end end
Graphics.update
Input.update
update
if Input.trigger?(Input::DOWN) && @wager < 3 && @sprites["credit"].score > 0 if Input.trigger?(Input::DOWN) && @wager < 3 && @sprites["credit"].score > 0
pbSEPlay("Slots coin") pbSEPlay("Slots coin")
@wager += 1 @wager += 1
@@ -347,20 +361,19 @@ class SlotMachineScene
(Input.trigger?(Input::USE) && @wager > 0) || @replay (Input.trigger?(Input::USE) && @wager > 0) || @replay
if @replay if @replay
@wager = 3 @wager = 3
(1..5).each do |i| (1..5).each { |i| @sprites["row#{i}"].visible = true }
@sprites["row#{i}"].visible = true
end
end end
@sprites["reel1"].startSpinning @sprites["reel1"].startSpinning
@sprites["reel2"].startSpinning @sprites["reel2"].startSpinning
@sprites["reel3"].startSpinning @sprites["reel3"].startSpinning
frame = 0
@gameRunning = true @gameRunning = true
elsif Input.trigger?(Input::BACK) && @wager == 0 elsif Input.trigger?(Input::BACK) && @wager == 0
break break
end end
break if @gameRunning
end
break if !@gameRunning
end end
frame = (frame + 1) % (Graphics.frame_rate * 4)
end end
old_coins = $player.coins old_coins = $player.coins
$player.coins = @sprites["credit"].score $player.coins = @sprites["credit"].score

View File

@@ -94,10 +94,11 @@ class VoltorbFlip
pbUpdateCoins pbUpdateCoins
# Draw curtain effect # Draw curtain effect
if @firstRound if @firstRound
angleDiff = 10 * 20 / Graphics.frame_rate curtain_duration = 0.5
timer_start = System.uptime
loop do loop do
@sprites["curtainL"].angle -= angleDiff @sprites["curtainL"].angle = lerp(-90, -180, curtain_duration, timer_start, System.uptime)
@sprites["curtainR"].angle += angleDiff @sprites["curtainR"].angle = lerp(0, 90, curtain_duration, timer_start, System.uptime)
Graphics.update Graphics.update
Input.update Input.update
update update
@@ -535,9 +536,9 @@ class VoltorbFlip
@sprites["cursor"].bitmap.clear @sprites["cursor"].bitmap.clear
end end
# def pbWaitText(msg,frames) # def pbWaitText(msg, frames)
# msgwindow=pbCreateMessageWindow # msgwindow = pbCreateMessageWindow
# pbMessageDisplay(msgwindow,msg) # pbMessageDisplay(msgwindow, msg)
# pbWait(frames / 20.0) # pbWait(frames / 20.0)
# pbDisposeMessageWindow(msgwindow) # pbDisposeMessageWindow(msgwindow)
# end # end
@@ -548,12 +549,11 @@ class VoltorbFlip
# Draw curtain effect # Draw curtain effect
@sprites["curtainL"].visible = true @sprites["curtainL"].visible = true
@sprites["curtainR"].visible = true @sprites["curtainR"].visible = true
angleDiff = 18 * 20 / Graphics.frame_rate curtain_duration = 0.25
timer_start = System.uptime
loop do loop do
@sprites["curtainL"].angle += angleDiff @sprites["curtainL"].angle = lerp(-180, -90, curtain_duration, timer_start, System.uptime)
@sprites["curtainR"].angle -= angleDiff @sprites["curtainR"].angle = lerp(90, 0, curtain_duration, timer_start, System.uptime)
# Fixes a minor graphical bug
@sprites["curtainL"].y -= 2 if @sprites["curtainL"].angle >= -90
Graphics.update Graphics.update
Input.update Input.update
update update

View File

@@ -489,23 +489,26 @@ class MiningGameScene
def pbFlashItems(revealed) def pbFlashItems(revealed)
return if revealed.length <= 0 return if revealed.length <= 0
revealeditems = BitmapSprite.new(Graphics.width, Graphics.height, @viewport) revealeditems = BitmapSprite.new(Graphics.width, Graphics.height, @viewport)
halfFlashTime = Graphics.frame_rate / 8 revealeditems.color = Color.new(255, 255, 255, 0)
alphaDiff = (255.0 / halfFlashTime).ceil flash_duration = 0.25
(1..halfFlashTime * 2).each do |i| 2.times do |i|
alpha_start = (i == 0) ? 0 : 255
alpha_end = (i == 0) ? 255 : 0
timer_start = System.uptime
loop do
revealed.each do |index| revealed.each do |index|
burieditem = @items[index] burieditem = @items[index]
revealeditems.bitmap.blt(32 * burieditem[1], 64 + (32 * burieditem[2]), revealeditems.bitmap.blt(32 * burieditem[1], 64 + (32 * burieditem[2]),
@itembitmap.bitmap, @itembitmap.bitmap,
Rect.new(32 * ITEMS[burieditem[0]][2], 32 * ITEMS[burieditem[0]][3], Rect.new(32 * ITEMS[burieditem[0]][2], 32 * ITEMS[burieditem[0]][3],
32 * ITEMS[burieditem[0]][4], 32 * ITEMS[burieditem[0]][5])) 32 * ITEMS[burieditem[0]][4], 32 * ITEMS[burieditem[0]][5]))
if i > halfFlashTime
revealeditems.color = Color.new(255, 255, 255, ((halfFlashTime * 2) - i) * alphaDiff)
else
revealeditems.color = Color.new(255, 255, 255, i * alphaDiff)
end
end end
flash_alpha = lerp(alpha_start, alpha_end, flash_duration / 2, timer_start, System.uptime)
revealeditems.color.alpha = flash_alpha
update update
Graphics.update Graphics.update
break if flash_alpha == alpha_end
end
end end
revealeditems.dispose revealeditems.dispose
revealed.each do |index| revealed.each do |index|