O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Smooth Scrolling

Iniciado por Raizen, 16/12/2012 às 17:24

Smooth Scrolling


Informações sobre o sistema

Nome: Smooth Scrolling
Autor: Toby Zerner


  • Incompatibilidade: Média ¹
  • Lag gerado: Desprezível ²
  • Customizável: Sim
  • Requer Recursos Extras: Não
[box class=catbg2]
Resumo
[/box][box class=catbg4]  Faz com que a tela do jogo, siga o personagem de maneira mais suave, ou seja, a câmera dá uma "vantagem" ao jogador e depois desliza para centralizá-lo na tela. Em miúdos, é um efeito bem interessante para a maioria dos jogos. O script foi testado em jogos on-line e funciona. Testado pelo membro [user]lierbag001[/user].[/box]


[box class=catbg2]
Descrição Detalhada
[/box]
O script suaviza os movimentos da tela do jogo, por padrão no RM o personagem sempre fica estritamente centralizado na tela, a não ser que esteja perto das bordas do mapa, com esse script, a sensação que o jogador tem é a de que primeiro o personagem se move e depois a tela o segue, centralizando-o suavemente depois de ele parar de se mover. É um efeito bem interessante, que se enquadra bem na maioria dos jogos e por não requerer recursos extras, não é custoso utilizá-lo. Ele pode ser incompatível com algum outro script que altere algo do mapa, da tela, dos eventos, dos eventos comuns ou da neblina (fog). Para customizá-lo, altere os números da linha 20 e 22 do script, quanto maior os valores, mais suave o movimento, quanto menor, mais semelhante ao movimento padrão do RMXP, o autor do script sugere 4, eu preferi o efeito com 10... Você, configura ao seu gosto. xD

[box class=catbg2]
Mídia
[/box]
Não dá para perceber o efeito por screens, simplesmente faça um mapa grande em um projeto qualquer com o script e comece a andar, você perceberá o efeito.

  Caso queira ver o efeito em ação, aqui tem o video, que mostra um jogo com o script (observe o movimento da câmera):

[box class=catbg2]
Código
[/box]
#==============================================================================
# ** 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 ealier on) [default: 4]
    @deceleration_start = 10
    # How fast to decelerate (bigger numbers mean quicker) [default: 4]
    @deceleration_speed = 10
    # -- 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


[box class=catbg2]
Demo
[/box]

Demo original em inglês feita pelo autor do script:
http://www.mediafire.com/?6n2mxbumemt

[box class=catbg2]
Agradecimentos
[/box]
Toby Zerner - Autor do script e da demo
[user]lierbag001[/user] - Por testar em modo On-line


Qualquer problema, dúvida ou o que for, é só postar ;D




¹ Critério avaliado de forma pessoal, baseada em experiência própria com scripts... A informação pode estar errada.
² Em vários testes o script praticamente não surtiu grandes efeitos na taxa de FPS, que manteu-se em 39~40.