Code:
#==============================================================================
# ** Smooth_Scrolling
#------------------------------------------------------------------------------
# Script by Toby Zerner
# Gives scrolling a 'smooth' effect (deceleration).
#==============================================================================
class Game_Map
attr_accessor :deceleration_start
attr_accessor :deceleration_speed
#--------------------------------------------------------------------------
# * Setup
# map_id : map ID
#--------------------------------------------------------------------------
alias ss_setup setup
def setup(map_id)
# -- CONFIGURATION VARIABLES
# When to start decelerating (bigger numbers mean earlier on) [default: 4]
@deceleration_start = 4
# How fast to decelerate (bigger numbers mean quicker) [default: 4]
@deceleration_speed = 4
# -- END CONFIGURATION VARIABLES
# Call the old setup method
ss_setup(map_id)
# Initialize smooth scrolling variables
# scroll_remain: the number of pixels * 4 the still need to be scrolled
@scroll_remain_x = 0
@scroll_remain_y = 0
# scroll_take: the number of pixels * 4 that are being scrolled every frame
# i.e. scrolling speed
@scroll_take_x = 0
@scroll_take_y = 0
# scroll_decel: variables for calculating decelaration
@scroll_decel_x = 0
@scroll_decel_y = 0
end
#--------------------------------------------------------------------------
# * Scroll Down
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_down(distance)
# Ceil the distance
distance = distance.ceil
# If the map is scrolling from an event command, then use that scroll speed
if scrolling? then @scroll_take_y = 2 ** @scroll_speed
# If the map is not scrolling
else
# Make sure the distance is always divisible by 4
if distance.ceil % 4 == 0 then @scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2 then @scroll_take_y = distance.ceil - distance.ceil % 4
else @scroll_take_y = distance.ceil + (4 - (distance.ceil % 4)) end
end
# If scrolling coordinates are inside the map's boundaries
unless @display_y + @scroll_remain_y + distance > (self.height - 15) * 128
# Add onto the amount left to be scrolled
@scroll_remain_y += distance
end
end
#--------------------------------------------------------------------------
# * Scroll Left
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_left(distance)
# Ceil the distance
distance = distance.ceil
# If the map is scrolling from an event command, then use that scroll speed
if scrolling? then @scroll_take_x = 2 ** @scroll_speed
# If the map is not scrolling
else
# Make sure the distance is always divisible by 4
if distance.ceil % 4 == 0 then @scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2 then @scroll_take_x = distance.ceil - distance.ceil % 4
else @scroll_take_x = distance.ceil + (4 - (distance.ceil % 4)) end
end
# If scrolling coordinates are inside the map's boundaries
unless @display_x - @scroll_remain_x - distance < 0
# Add onto the amount left to be scrolled
@scroll_remain_x -= distance
end
end
#--------------------------------------------------------------------------
# * Scroll Right
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_right(distance)
# Ceil the distance
distance = distance.ceil
# If the map is scrolling from an event command, then use that scroll speed
if scrolling? then @scroll_take_x = 2 ** @scroll_speed
# If the map is not scrolling
else
# Make sure the distance is always divisible by 4
if distance.ceil % 4 == 0 then @scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2 then @scroll_take_x = distance.ceil - distance.ceil % 4
else @scroll_take_x = distance.ceil + (4 - (distance.ceil % 4)) end
end
# If scrolling coordinates are inside the map's boundaries
unless @display_x + @scroll_remain_x + distance > (self.width - 20) * 128
# Add onto the amount left to be scrolled
@scroll_remain_x += distance
end
end
#--------------------------------------------------------------------------
# * Scroll Up
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_up(distance)
# Ceil the distance
distance = distance.ceil
# If the map is scrolling from an event command, then use that scroll speed
if scrolling? then @scroll_take_y = 2 ** @scroll_speed
# If the map is not scrolling
else
# Make sure the distance is always divisible by 4
if distance.ceil % 4 == 0 then @scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2 then @scroll_take_y = distance.ceil - distance.ceil % 4
else @scroll_take_y = distance.ceil + (4 - (distance.ceil % 4)) end
end
# If scrolling coordinates are inside the map's boundaries
unless @display_y - @scroll_remain_y - distance < 0
# Add onto the amount left to be scrolled
@scroll_remain_y -= distance
end
end
#--------------------------------------------------------------------------
# * Start Scroll
# direction : scroll direction
# distance : scroll distance
# speed : scroll speed
#--------------------------------------------------------------------------
def start_scroll(direction, distance, speed)
# Set scrolling variables
distance = distance.ceil * 128
@scroll_direction = direction
@scroll_speed = speed
@scroll_rest = distance
# Execute scrolling
case @scroll_direction
when 2 # Down
scroll_down(@scroll_rest)
when 4 # Left
scroll_left(@scroll_rest)
when 6 # Right
scroll_right(@scroll_rest)
when 8 # Up
scroll_up(@scroll_rest)
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
# This method could not be aliased because the scrolling part of the old
# method has been rewritten.
#--------------------------------------------------------------------------
def update
# Refresh map if necessary
if $game_map.need_refresh
refresh
end
#--------------------------------------------------------
# If the map is still scrolling
if @scroll_rest > 0 then @scroll_rest -= 2 ** @scroll_speed end
# If the x axis needs to be scrolled to the right
if @scroll_remain_x > 0
# If the amount to be scrolled is close enough to 0 to decelerate
if @scroll_remain_x <= @scroll_take_x * @deceleration_start
old_display_x = @display_x
# Add onto the deceleration variable
@scroll_decel_x += @deceleration_speed
# Work out how much to scroll
distance = [@scroll_take_x - @scroll_decel_x, 4].max
# If the scrolling coordinates are within the map's boundaries
unless @display_x + distance > (self.width - 20) * 128
@display_x += distance
end
# Subtract the amount that was scrolled
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x < 0 then @scroll_remain_x = 0 end
# Otherwise, scroll at a normal speed
else
# Reset the deceleration variable
@scroll_decel_x = 0
# If the scrolling coordinates are out of range
if @display_x + @scroll_take_x > (self.width - 20) * 128
@display_x = (self.width - 20) * 128
@scroll_remain_x = 0
# Otherwise, scroll normally
else
@display_x += @scroll_take_x
@scroll_remain_x -= @scroll_take_x
end
end
# If the x axis needs to be scrolled to the left
elsif @scroll_remain_x < 0
# If the amount to be scrolled is close enough to 0 to decelerate
if @scroll_remain_x >= -@scroll_take_x * @deceleration_start
old_display_x = @display_x
# Add onto the deceleration variable
@scroll_decel_x += @deceleration_speed
# Work out how much to scroll
distance = [@scroll_take_x - @scroll_decel_x, 4].max
# If the scrolling coordinates are within the map's boundaries
unless @display_x - distance < 0
@display_x -= distance
end
# Subtract the amount that was scrolled
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x > 0 then @scroll_remain_x = 0 end
# Otherwise, scroll at a normal speed
else
# Reset the deceleration variable
@scroll_decel_x = 0
# If the scrolling coordinates are out of range
if @display_x - @scroll_take_x < 0
@display_x = 0
@scroll_remain_x = 0
# Otherwise, scroll normally
else
@display_x -= @scroll_take_x
@scroll_remain_x += @scroll_take_x
end
end
# If no x scrolling needs to be done, reset the deceleration variable
else @scroll_decel_x = 0 end
# If the y axis needs to be scrolled downwards
if @scroll_remain_y > 0
# If the amount to be scrolled is close enough to 0 to decelerate
if @scroll_remain_y <= @scroll_take_y * @deceleration_start
old_display_y = @display_y
# Add onto the deceleration variable
@scroll_decel_y += @deceleration_speed
# Work out how much to scroll
distance = [@scroll_take_y - @scroll_decel_y, 4].max
# If the scrolling coordinates are within the map's boundaries
unless @display_y + distance > (self.height - 15) * 128
@display_y += distance
end
# Subtract the amount that was scrolled
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y < 0 then @scroll_remain_y = 0 end
# Otherwise, scroll at a normal speed
else
# Reset the deceleration variable
@scroll_speed_accel_y = 0
# If the scrolling coordinates are out of range
if @display_y + @scroll_take_y > (self.height - 15) * 128
@display_y = (self.height - 15) * 128
@scroll_remain_y = 0
# Otherwise, scroll normally
else
@display_y += @scroll_take_y
@scroll_remain_y -= @scroll_take_y
end
end
# If the y axis needs to be scrolled downwards
elsif @scroll_remain_y < 0
# If the amount to be scrolled is close enough to 0 to decelerate
if @scroll_remain_y >= -@scroll_take_y * @deceleration_start
old_display_y = @display_y
# Add onto the deceleration variable
@scroll_decel_y += @deceleration_speed
# Work out how much to scroll
distance = [@scroll_take_y - @scroll_decel_y, 4].max
# If the scrolling coordinates are within the map's boundaries
unless @display_y - distance < 0
@display_y -= distance
end
# Subtract the amount that was scrolled
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y > 0 then @scroll_remain_y = 0 end
# Otherwise, scroll at a normal speed
else
# Reset the deceleration variable
@scroll_speed_accel_y = 0
# If the scrolling coordinates are out of range
if @display_y - @scroll_take_y < 0
@display_y = 0
@scroll_remain_y = 0
# Otherwise, scroll normally
else
@display_y -= @scroll_take_y
@scroll_remain_y += @scroll_take_y
end
end
# If no y scrolling needs to be done, reset the deceleration variable
else @scroll_decel_y = 0 end
#--------------------------------------------------------
# Update map event
for event in @events.values
event.update
end
# Update common event
for common_event in @common_events.values
common_event.update
end
# Manage fog scrolling
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
# Manage change in fog color tone
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
# Manage change in fog opacity level
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