Removed last possible usages of Graphics.frame_rate and Graphics.frame_count, improved screen scrolling code, player now animates walking into a wall

This commit is contained in:
Maruno17
2023-05-28 17:25:30 +01:00
parent f27841a7f8
commit 68de25562a
27 changed files with 643 additions and 1124 deletions

View File

@@ -28,7 +28,6 @@ class Game_Screen
@shake_power = 0
@shake_speed = 0
@shake_duration = 0
@shake_direction = 1
@shake = 0
@pictures = [nil]
(1..100).each { |i| @pictures.push(Game_Picture.new(i)) }
@@ -43,9 +42,9 @@ class Game_Screen
@tone = tone.clone
return
end
@tone_initial = @tone.clone
@tone_target = tone.clone
@tone_duration = duration / 20.0
@tone_initial = @tone.clone
@tone_target = tone.clone
@tone_duration = duration / 20.0
@tone_timer_start = $stats.play_time
end
@@ -57,16 +56,19 @@ class Game_Screen
@flash_timer_start = $stats.play_time
end
# duration is time in 1/20ths of a second.
def start_shake(power, speed, duration)
@shake_power = power
@shake_speed = speed
@shake_duration = duration
@shake_power = power
@shake_speed = speed
@shake_duration = duration / 20.0
@shake_timer_start = $stats.play_time
end
# duration is time in 1/20ths of a second.
def weather(type, power, duration)
@weather_type = GameData::Weather.get(type).id
@weather_max = (power + 1) * RPG::Weather::MAX_SPRITES / 10
@weather_duration = duration # In 1/20ths of a seconds
@weather_duration = duration
end
def update
@@ -98,16 +100,25 @@ class Game_Screen
@flash_timer_start = nil
end
end
if @shake_duration >= 1 || @shake != 0
delta = (@shake_power * @shake_speed * @shake_direction) / 10.0
if @shake_duration <= 1 && @shake * (@shake + delta) < 0
@shake = 0
if @shake_timer_start
delta_t = now - @shake_timer_start
movement_per_second = @shake_power * @shake_speed * 4
limit = @shake_power * 2.5 # Maximum pixel displacement
phase = (delta_t * movement_per_second / limit).to_i % 4
if phase == 0 || phase == 2
@shake = (movement_per_second * delta_t) % limit
@shake *= -1 if phase == 2
else
@shake += delta
@shake = limit - ((movement_per_second * delta_t) % limit)
@shake *= -1 if phase == 3
end
if delta_t >= @shake_duration
@shake_phase = phase if !@shake_phase || phase == 1 || phase == 3
if phase != @shake_phase || @shake < 2
@shake_timer_start = nil
@shake = 0
end
end
@shake_direction = -1 if @shake > @shake_power * 2
@shake_direction = 1 if @shake < -@shake_power * 2
@shake_duration -= 1 if @shake_duration >= 1
end
if $game_temp.in_battle
(51..100).each { |i| @pictures[i].update }
@@ -130,5 +141,5 @@ def pbFlash(color, frames)
end
def pbShake(power, speed, frames)
$game_screen.start_shake(power, speed, frames * Graphics.frame_rate / 20)
$game_screen.start_shake(power, speed, frames)
end

View File

@@ -68,8 +68,8 @@ class Game_Map
(1...$data_common_events.size).each do |i|
@common_events[i] = Game_CommonEvent.new(i)
end
@scroll_direction = 2
@scroll_rest = 0
@scroll_distance_x = 0
@scroll_distance_y = 0
@scroll_speed = 4
end
@@ -356,18 +356,42 @@ class Game_Map
self.display_x += distance
end
def start_scroll(direction, distance, speed)
@scroll_direction = direction
if [2, 8].include?(direction) # down or up
@scroll_rest = distance * REAL_RES_Y
else
@scroll_rest = distance * REAL_RES_X
# speed is:
# 1: moves 1 tile in 1.6 seconds
# 2: moves 1 tile in 0.8 seconds
# 3: moves 1 tile in 0.4 seconds
# 4: moves 1 tile in 0.2 seconds
# 5: moves 1 tile in 0.1 seconds
# 6: moves 1 tile in 0.05 seconds
def start_scroll(direction, distance, speed = 4)
return if direction <= 0 || direction == 5 || direction >= 10
if [1, 3, 4, 6, 7, 9].include(direction) # horizontal
@scroll_distance_x = distance
@scroll_distance_x *= -1 if [1, 4, 7].include?(direction)
end
if [1, 2, 3, 7, 8, 9].include?(direction) # vertical
@scroll_distance_y = distance
@scroll_distance_y *= -1 if [7, 8, 9].include?(direction)
end
@scroll_speed = speed
@scroll_start_x = display_x
@scroll_start_y = display_y
@scroll_timer_start = System.uptime
end
# The two distances can be positive or negative.
def start_scroll_custom(distance_x, distance_y, speed = 4)
return if distance_x == 0 && distance_y == 0
@scroll_distance_x = distance_x
@scroll_distance_y = distance_y
@scroll_speed = speed
@scroll_start_x = display_x
@scroll_start_y = display_y
@scroll_timer_start = System.uptime
end
def scrolling?
return @scroll_rest > 0
return (@scroll_distance_x || 0) != 0 || (@scroll_distance_y || 0) != 0
end
# duration is time in 1/20ths of a second.
@@ -419,16 +443,17 @@ class Game_Map
$map_factory.setCurrentMap
end
# If scrolling
if @scroll_rest > 0
distance = (1 << @scroll_speed) * 40.0 / Graphics.frame_rate
distance = @scroll_rest if distance > @scroll_rest
case @scroll_direction
when 2 then scroll_down(distance)
when 4 then scroll_left(distance)
when 6 then scroll_right(distance)
when 8 then scroll_up(distance)
end
@scroll_rest -= distance
if (@scroll_distance_x || 0) != 0
duration = @scroll_distance_x.abs * TILE_WIDTH.to_f / (10 * (2**@scroll_speed))
scroll_offset = lerp(0, @scroll_distance_x, duration, @scroll_timer_start, System.uptime)
self.display_x = @scroll_start_x + scroll_offset * REAL_RES_X
@scroll_distance_x = 0 if scroll_offset == @scroll_distance_x
end
if (@scroll_distance_y || 0) != 0
duration = @scroll_distance_y.abs * TILE_HEIGHT.to_f / (10 * (2**@scroll_speed))
scroll_offset = lerp(0, @scroll_distance_y, duration, @scroll_timer_start, System.uptime)
self.display_y = @scroll_start_y + scroll_offset * REAL_RES_Y
@scroll_distance_y = 0 if scroll_offset == @scroll_distance_y
end
# Only update events that are on-screen
if !$game_temp.in_menu
@@ -463,26 +488,74 @@ end
#===============================================================================
#
#===============================================================================
def pbScrollMap(direction, distance, speed)
# Scroll the map in the given direction by the given distance at the (optional)
# given speed.
def pbScrollMap(direction, distance, speed = 4)
if speed == 0
case direction
when 2 then $game_map.scroll_down(distance * Game_Map::REAL_RES_Y)
when 4 then $game_map.scroll_left(distance * Game_Map::REAL_RES_X)
when 6 then $game_map.scroll_right(distance * Game_Map::REAL_RES_X)
when 8 then $game_map.scroll_up(distance * Game_Map::REAL_RES_Y)
if [1, 2, 3].include?(direction)
$game_map.scroll_down(distance * Game_Map::REAL_RES_Y)
elsif [7, 8, 9].include?(direction)
$game_map.scroll_up(distance * Game_Map::REAL_RES_Y)
end
if [3, 6, 9].include?(direction)
$game_map.scroll_right(distance * Game_Map::REAL_RES_X)
elsif [1, 4, 7].include?(direction)
$game_map.scroll_left(distance * Game_Map::REAL_RES_X)
end
else
$game_map.start_scroll(direction, distance, speed)
oldx = $game_map.display_x
oldy = $game_map.display_y
loop do
Graphics.update
Input.update
break if !$game_map.scrolling?
pbUpdateSceneMap
break if $game_map.display_x == oldx && $game_map.display_y == oldy
oldx = $game_map.display_x
oldy = $game_map.display_y
break if !$game_map.scrolling?
end
end
end
# Scroll the map to center on the given coordinates at the (optional) given
# speed. The scroll can happen in up to two parts, depending on where the target
# is relative to the current location: an initial diagonal movement and a
# following cardinal (vertical/horizontal) movement.
def pbScrollMapTo(x, y, speed = 4)
if !$game_map.valid?(x, y)
print "pbScrollMapTo: given x,y is invalid"
return
elsif !(0..6).include?(speed)
print "pbScrollMapTo: invalid speed (0-6 only)"
return
end
# Get tile coordinates that the screen is currently scrolled to
screen_offset_x = (Graphics.width - Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS / 2
screen_offset_y = (Graphics.height - Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS / 2
current_tile_x = ($game_map.display_x + screen_offset_x) / Game_Map::REAL_RES_X
current_tile_y = ($game_map.display_y + screen_offset_y) / Game_Map::REAL_RES_Y
offset_x = x - current_tile_x
offset_y = y - current_tile_y
return if offset_x == 0 && offset_y == 0
if speed == 0
if offset_y > 0
$game_map.scroll_down(offset_y.abs * Game_Map::REAL_RES_Y)
elsif offset_y < 0
$game_map.scroll_up(offset_y.abs * Game_Map::REAL_RES_Y)
end
if offset_x > 0
$game_map.scroll_right(offset_x.abs * Game_Map::REAL_RES_X)
elsif offset_x < 0
$game_map.scroll_left(offset_x.abs * Game_Map::REAL_RES_X)
end
else
$game_map.start_scroll_custom(offset_x, offset_y, speed)
loop do
Graphics.update
Input.update
pbUpdateSceneMap
break if !$game_map.scrolling?
end
end
end
# Scroll the map to center on the player at the (optional) given speed.
def pbScrollMapToPlayer(speed = 4)
pbScrollMapTo($game_player.x, $game_player.y, speed)
end

View File

@@ -1,189 +0,0 @@
#===============================================================================
# ** Map Autoscroll
#-------------------------------------------------------------------------------
# Wachunga
# Version 1.02
# 2005-12-18
#===============================================================================
#
# This script supplements the built-in "Scroll Map" event command with the
# aim of simplifying cutscenes (and map scrolling in general). Whereas the
# normal event command requires a direction and number of tiles to scroll,
# Map Autoscroll scrolls the map to center on the tile whose x and y
# coordinates are given.
#
# FEATURES
# - automatic map scrolling to given x,y coordinate (or player)
# - destination is fixed, so it's possible to scroll to same place even if
# origin is variable (e.g. moving NPC)
# - variable speed (just like "Scroll Map" event command)
# - diagonal scrolling supported
#
# SETUP
# Instead of a "Scroll Map" event command, use the "Call Script" command
# and enter on the following on the first line:
#
# autoscroll(x,y)
#
# (replacing "x" and "y" with the x and y coordinates of the tile to scroll to)
#
# To specify a scroll speed other than the default (4), use:
#
# autoscroll(x,y,speed)
#
# (now also replacing "speed" with the scroll speed from 1-6)
#
# Diagonal scrolling happens automatically when the destination is diagonal
# relative to the starting point (i.e., not directly up, down, left or right).
#
# To scroll to the player, instead use the following:
#
# autoscroll_player(speed)
#
# Note: because of how the interpreter and the "Call Script" event command
# are setup, the call to autoscroll(...) can only be on the first line of
# the "Call Script" event command (and not flowing down to subsequent lines).
#
# For example, the following call may not work as expected:
#
# autoscroll($game_variables[1],
# $game_variables[2])
#
# (since the long argument names require dropping down to a second line)
# A work-around is to setup new variables with shorter names in a preceding
# (separate) "Call Script" event command:
#
# @x = $game_variables[1]
# @y = $game_variables[2]
#
# and then use those as arguments:
#
# autoscroll(@x,@y)
#
# The renaming must be in a separate "Call Script" because otherwise
# the call to autoscroll(...) isn't on the first line.
#
# Originally requested by militantmilo80:
# http://www.rmxp.net/forums/index.php?showtopic=29519
#
#===============================================================================
#===============================================================================
#
#===============================================================================
class Interpreter
SCROLL_SPEED_DEFAULT = 4
# Map Autoscroll to Coordinates
# x : x coordinate to scroll to and center on
# y : y coordinate to scroll to and center on
# speed : (optional) scroll speed (from 1-6, default being 4)
def autoscroll(x, y, speed = SCROLL_SPEED_DEFAULT)
if $game_map.scrolling?
return false
elsif !$game_map.valid?(x, y)
print "Map Autoscroll: given x,y is invalid"
return command_skip
elsif !(1..6).include?(speed)
print "Map Autoscroll: invalid speed (1-6 only)"
return command_skip
end
center_x = ((Graphics.width / 2) - (Game_Map::TILE_WIDTH / 2)) * 4 # X coordinate in the center of the screen
center_y = ((Graphics.height / 2) - (Game_Map::TILE_HEIGHT / 2)) * 4 # Y coordinate in the center of the screen
max_x = ($game_map.width - (Graphics.width.to_f / Game_Map::TILE_WIDTH)) * 4 * Game_Map::TILE_WIDTH
max_y = ($game_map.height - (Graphics.height.to_f / Game_Map::TILE_HEIGHT)) * 4 * Game_Map::TILE_HEIGHT
count_x = ($game_map.display_x - [0, [(x * Game_Map::REAL_RES_X) - center_x, max_x].min].max) / Game_Map::REAL_RES_X
count_y = ($game_map.display_y - [0, [(y * Game_Map::REAL_RES_Y) - center_y, max_y].min].max) / Game_Map::REAL_RES_Y
if @diag
@diag = false
dir = nil
if count_x != 0 && count_y != 0
return false
elsif count_x > 0
dir = 4
elsif count_x < 0
dir = 6
elsif count_y > 0
dir = 8
elsif count_y < 0
dir = 2
end
count = count_x == 0 ? count_y.abs : count_x.abs
else
@diag = true
dir = nil
if count_x > 0
if count_y > 0
dir = 7
elsif count_y < 0
dir = 1
end
elsif count_x < 0
if count_y > 0
dir = 9
elsif count_y < 0
dir = 3
end
end
count = [count_x.abs, count_y.abs].min
end
$game_map.start_scroll(dir, count, speed) if dir
return !@diag
end
# Map Autoscroll (to Player)
# speed : (optional) scroll speed (from 1-6, default being 4)
def autoscroll_player(speed = SCROLL_SPEED_DEFAULT)
autoscroll($game_player.x, $game_player.y, speed)
end
end
#===============================================================================
#
#===============================================================================
class Game_Map
def scroll_downright(distance)
@display_x = [@display_x + distance,
(self.width - (Graphics.width.to_f / TILE_WIDTH)) * REAL_RES_X].min
@display_y = [@display_y + distance,
(self.height - (Graphics.height.to_f / TILE_HEIGHT)) * REAL_RES_Y].min
end
def scroll_downleft(distance)
@display_x = [@display_x - distance, 0].max
@display_y = [@display_y + distance,
(self.height - (Graphics.height.to_f / TILE_HEIGHT)) * REAL_RES_Y].min
end
def scroll_upright(distance)
@display_x = [@display_x + distance,
(self.width - (Graphics.width.to_f / TILE_WIDTH)) * REAL_RES_X].min
@display_y = [@display_y - distance, 0].max
end
def scroll_upleft(distance)
@display_x = [@display_x - distance, 0].max
@display_y = [@display_y - distance, 0].max
end
def update_scrolling
# If scrolling
if @scroll_rest > 0
# Change from scroll speed to distance in map coordinates
distance = (1 << @scroll_speed) * 40 / Graphics.frame_rate
distance = @scroll_rest if distance > @scroll_rest
# Execute scrolling
case @scroll_direction
when 1 then scroll_downleft(distance)
when 2 then scroll_down(distance)
when 3 then scroll_downright(distance)
when 4 then scroll_left(distance)
when 6 then scroll_right(distance)
when 7 then scroll_upleft(distance)
when 8 then scroll_up(distance)
when 9 then scroll_upright(distance)
end
# Subtract distance scrolled
@scroll_rest -= distance
end
end
end

View File

@@ -72,6 +72,7 @@ class Game_Character
@always_on_top = false
@anime_count = 0 # Time since pattern was last changed
@stop_count = 0 # Time since character last finished moving
@bumping = false # Used by the player only when walking into something
@jump_peak = 0 # Max height while jumping
@jump_distance = 0 # Total distance of jump
@jump_fraction = 0 # How far through a jump we currently are (0-1)
@@ -337,8 +338,7 @@ class Game_Character
# Movement
#=============================================================================
def moving?
return @real_x != @x * Game_Map::REAL_RES_X ||
@real_y != @y * Game_Map::REAL_RES_Y
return !@move_timer.nil?
end
def jumping?
@@ -955,8 +955,10 @@ class Game_Character
@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?
if moving? && @move_timer >= @move_time &&
@real_x == @x * Game_Map::REAL_RES_X && @real_y == @y * Game_Map::REAL_RES_Y
@move_timer = nil
@bumping = false
end
# End of jump
if jumping? && @jump_fraction >= 1

View File

@@ -6,20 +6,19 @@
# instance of this class.
#===============================================================================
class Game_Player < Game_Character
attr_accessor :bump_se
attr_accessor :charsetData
attr_accessor :encounter_count
SCREEN_CENTER_X = ((Settings::SCREEN_WIDTH / 2) - (Game_Map::TILE_WIDTH / 2)) * Game_Map::X_SUBPIXELS
SCREEN_CENTER_Y = ((Settings::SCREEN_HEIGHT / 2) - (Game_Map::TILE_HEIGHT / 2)) * Game_Map::Y_SUBPIXELS
@@bobFrameSpeed = 1.0 / 15
# Time in seconds for one cycle of bobbing (playing 4 charset frames) while
# surfing or diving.
SURF_BOB_DURATION = 1.5
def initialize(*arg)
super(*arg)
@lastdir = 0
@lastdirframe = 0
@bump_se = 0
end
def map
@@ -52,6 +51,7 @@ class Game_Player < Game_Character
def can_run?
return @move_speed > 3 if @move_route_forcing
return false if @bumping
return false if $game_temp.in_menu || $game_temp.in_battle ||
$game_temp.message_window_showing || pbMapInterpreterRunning?
return false if !$player.has_running_shoes && !$PokemonGlobal.diving &&
@@ -92,6 +92,7 @@ class Game_Player < Game_Character
self.move_speed = 3 if !@move_route_forcing
new_charset = pbGetPlayerCharset(meta.walk_charset)
end
self.move_speed = 3 if @bumping
@character_name = new_charset if new_charset
end
@@ -115,9 +116,12 @@ class Game_Player < Game_Character
#-----------------------------------------------------------------------------
def bump_into_object
return if @bump_se && @bump_se > 0
pbSEPlay("Player bump") if !@move_route_forcing
@bump_se = Graphics.frame_rate / 4
$stats.bump_count += 1
@move_initial_x = @x
@move_initial_y = @y
@move_timer = 0.0
@bumping = true
end
def add_move_distance_to_stats(distance = 1)
@@ -412,8 +416,6 @@ class Game_Player < Game_Character
$game_temp.followers.move_followers
end
$game_temp.followers.update
# Count down the time between allowed bump sounds
@bump_se -= 1 if @bump_se && @bump_se > 0
update_event_triggering
end
@@ -425,7 +427,7 @@ class Game_Player < Game_Character
!$game_temp.in_mini_update && !$game_temp.in_menu
# Move player in the direction the directional button is being pressed
if @moved_last_frame ||
(dir > 0 && dir == @lastdir && Graphics.frame_count - @lastdirframe > Graphics.frame_rate / 20)
(dir > 0 && dir == @lastdir && System.uptime - @lastdirframe >= 0.075)
case dir
when 2 then move_down
when 4 then move_left
@@ -440,10 +442,10 @@ class Game_Player < Game_Character
when 8 then turn_up
end
end
# Record last direction input
@lastdirframe = System.uptime if dir != @lastdir
@lastdir = dir
end
# Record last direction input
@lastdirframe = Graphics.frame_count if dir != @lastdir
@lastdir = dir
end
def update_move
@@ -501,10 +503,10 @@ class Game_Player < Game_Character
def update_pattern
if $PokemonGlobal&.surfing || $PokemonGlobal&.diving
p = ((Graphics.frame_count % 60) * @@bobFrameSpeed).floor
@pattern = p if !@lock_pattern
@pattern_surf = p
@bob_height = (p >= 2) ? 2 : 0
bob_pattern = (4 * System.uptime / SURF_BOB_DURATION).to_i % 4
@pattern = bob_pattern if !@lock_pattern
@pattern_surf = bob_pattern
@bob_height = (bob_pattern >= 2) ? 2 : 0
@anime_count = 0
else
@bob_height = 0

View File

@@ -5,6 +5,7 @@ class GameStats
# Travel
attr_accessor :distance_walked, :distance_cycled, :distance_surfed # surfed includes diving
attr_accessor :distance_slid_on_ice # Also counted in distance_walked
attr_accessor :bump_count # Times the player walked into something
attr_accessor :cycle_count, :surf_count, :dive_count
# Field actions
attr_accessor :fly_count, :cut_count, :flash_count
@@ -45,7 +46,7 @@ class GameStats
attr_accessor :mart_items_bought, :premier_balls_earned
attr_accessor :drinks_bought, :drinks_won # From vending machines
attr_accessor :coins_won, :coins_lost # Not bought, not spent
attr_accessor :battle_points_won, :battle_points_spent # Currently unused
attr_accessor :battle_points_won, :battle_points_spent
attr_accessor :soot_collected
# Special stats
attr_accessor :gym_leader_attempts # An array of integers
@@ -66,6 +67,7 @@ class GameStats
@distance_cycled = 0
@distance_surfed = 0
@distance_slid_on_ice = 0
@bump_count = 0
@cycle_count = 0
@surf_count = 0
@dive_count = 0
@@ -170,8 +172,9 @@ class GameStats
def play_time
if $game_temp&.last_uptime_refreshed_play_time
@play_time += System.uptime - $game_temp.last_uptime_refreshed_play_time
$game_temp.last_uptime_refreshed_play_time = System.uptime
now = System.uptime
@play_time += now - $game_temp.last_uptime_refreshed_play_time
$game_temp.last_uptime_refreshed_play_time = now
end
return @play_time
end