Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

HBGames

Smooth Scrolling
Version: 0.1

Introduction
This script gives map scrolling a 'smooth' effect, i.e. deceleration.

Screenshots
None needed. Download the demo (below) instead.

Demo
http://www.box.net/public/cr0jtvft0y
The demo also includes a small tutorial of how to alter the deceleration settings.

Script
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

Instructions
Paste the above script in a new slot above Main. Nothing else is essential to making this script work.

If you want to change the properties of the deceleration effect, you can either do so by editing the variables in the configuration part of the 'setup' method, or you can use the following in an event:
Code:
$game_map.deceleration_start = #
$game_map.deceleration_speed = #

Compatibility
This script alters the Game_Map class. It overwrites the following methods: update, scroll_start, scroll_down, scroll_right, scroll_left, scroll_up. Unfortunately, I could not alias the old methods, because the changes are too significant.

Credits and Thanks
Thanks to Alastyr for the moral support. :P

Author's Notes
Since I'm fairly new to RGSS scripting, this script may not be written in the most efficient way, nor may it work perfectly. If you have any suggestions as to how it can be improved, please let me know.

Currently, I have no plans for the next version. However, if you find any bugs, or would like a new feature added, don't hesitate to tell me; I'll be glad to update it. After all, I have too much spare time on my hands... -_-

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top