Galv’s Layer Graphics V.1.3

DEMO:
Demo – Version 1.2 > (Demo uses old version)

#------------------------------------------------------------------------------#
#  Galv's Layer Graphics
#------------------------------------------------------------------------------#
#  For: RPGMAKER VX ACE
#  Version 1.3
#------------------------------------------------------------------------------#
#  2013-03-22 - Version 1.3 - Fixed bug in y offset movement
#  2013-03-22 - Version 1.2 - Added layers in battles
#  2013-03-17 - Version 1.1 - fixed graphic object bug
#  2013-03-17 - Version 1.0 - release
#------------------------------------------------------------------------------#
#  Create image layers on maps using script calls. These image layers can be
#  used for overlay mapping, moving fogs etc.
#
#  Notes:
#  Once you have created a layer for a map, it will remain at the settings you
#  chose until you change it again. Layers don't carry over from map to map, you
#  will need to create the layer for each map required.
#  I recommend not using too many layers as it could start to cause lag.
#
#  There are other scripts available that do a similar thing, this is just my
#  implementation of it. I recommend trying the others out, too (as they are
#  possibly better!). I created this more for myself but thought I'd add it to
#  my archive for anyone to use.
#------------------------------------------------------------------------------#

#-------------------------------------------------------------------------------
#  SCRIPT CALLS:
#-------------------------------------------------------------------------------
#
#  layer_status(status)    # script enabled if status is true, disabled if false
#
#  del_layer(map_id,layer_id)       # removes a layer graphic from selected map
#
#  layer(map,layer,["Filename",xspeed,yspeed,opacity,z,blend,xoffset,yoffset])
#
#  #  map        - map id the layer is to be on
#  #  layer      - layer number. use different numbers for different layers
#  #  "Filename" - the name of the image located in Graphics/Layers/ folder
#  #  xspeed     - speed the layer will scroll horizontally
#  #  yspeed     - speed the layer will scroll vertically
#  #  opacity    - the opacity of the layer
#  #  z value    - what level the layer is displayed at (ground is 0)
#  #  blend      - 0 is normal, 1 is addition, 2 is subtraction
#  #  xoffset    - Moves the layer at a different amount than the map. Make
#  #  yoffset    - these 0 to fix the layer to the map.
#
#  refresh_layers     # When setting a NEW layer on the CURRENT map, you will
#                     # need to use the refresh_layers script call right after.
#                     # Updating an existing one or setting a layer for another
#                     # map doesn't require refreshing.
#
#-------------------------------------------------------------------------------
#  EXAMPLE SCRIPT CALLS:
#  layer(1,6,["water2",0.3,0.1,120,-5,0,0,0])   # adds/updates layer 6 on map 1
#  layer(2,1,["map2-over",0,0,255,700,0,10,0])  # adds/updates layer 1 on map 2
#
#  layer_status(false)    # turn layers OFF
#  layer_status(true)     # turn layers ON
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#  SCRIPT CALLS for BATTLE layers
#-------------------------------------------------------------------------------
#
#  del_blayer(layer_id)       # Removes a layer from battles.
#
#  refresh_layers             # Use this when adding a new laying during battle
#
#  blayer(layer,["Filename",xspeed,yspeed,opacity,z,blend,xoffset,yoffset])
#
#  #  These script calls add and remove layers that will appear in battle. They
#  #  work the same as map layers without the need for a map id at the start.
#  #  Ideally you would change the layers before combat, but they can be done
#  #  during as well, if you refresh the layers.
#
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#  NO SCRIPT SETTINGS. DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU ARE DOING.
#-------------------------------------------------------------------------------

($imported ||= {})["Galv_Layers"] = true
module Cache
  def self.layers(filename)
    load_bitmap("Graphics/Layers/", filename)
  end
end # Cache

class Spriteset_Map
  def create_layers
    @layer_images = []
    return if !$game_map.layer_status
    return if $game_map.layers[$game_map.map_id].nil?
    $game_map.layers[$game_map.map_id].each_with_index { |layer,i|
      if layer.nil?
        @layer_images.push(nil)
      else
        @layer_images.push(Layer_Graphic.new(@viewport1,i))
      end
    }
  end

  def update_layers
    @layer_images.each { |o| o.update if !o.nil? }
  end

  def dispose_layers
    @layer_images.each { |o| o.dispose if !o.nil? }
    @layer_images = []
  end

  def refresh_layers
    dispose_layers
    create_layers
  end

  alias galv_layers_sm_create_parallax create_parallax
  def create_parallax
    galv_layers_sm_create_parallax
    create_layers
  end
  alias galv_layers_sm_dispose_parallax dispose_parallax
  def dispose_parallax
    galv_layers_sm_dispose_parallax
    dispose_layers
  end

  alias galv_layers_sm_update_parallax update_parallax
  def update_parallax
    galv_layers_sm_update_parallax
    update_layers
  end
end # Spriteset_Map

class Spriteset_Battle
  def create_layers
    @layer_images = []
    return if !$game_map.layer_status
    return if $game_map.blayers.nil?
    $game_map.blayers.each_with_index { |layer,i|
      if layer.nil?
        @layer_images.push(nil)
      else
        @layer_images.push(Layer_Graphic.new(@viewport1,i))
      end
    }
  end

  def update_layers
    @layer_images.each { |o| o.update if !o.nil? }
  end

  def dispose_layers
    @layer_images.each { |o| o.dispose if !o.nil? }
    @layer_images = []
  end

  def refresh_layers
    dispose_layers
    create_layers
  end

  alias galv_layers_sb_create_battleback2 create_battleback2
  def create_battleback2
    galv_layers_sb_create_battleback2
    create_layers
  end

  alias galv_layers_sb_dispose dispose
  def dispose
    dispose_layers
    galv_layers_sb_dispose
  end

  alias galv_layers_sb_update update
  def update
    galv_layers_sb_update
    update_layers
  end
end # Spriteset_Battle

class Game_Map
  attr_accessor :blayers
  attr_accessor :layers
  attr_accessor :layer_status

  alias galv_layers_gm_initialize initialize
  def initialize
    galv_layers_gm_initialize
    @layer_status = true
    @layers = { 0 => [] }
    @blayers = []
  end

  alias galv_layers_gm_setup setup
  def setup(map_id)
    galv_layers_gm_setup(map_id)
    if SceneManager.scene_is?(Scene_Map)
      @layers[0] = []
      SceneManager.scene.spriteset.refresh_layers
    end
  end
end # Game_Map

class Scene_Map < Scene_Base
  attr_accessor :spriteset
end # Scene_Map < Scene_Base

class Scene_Battle < Scene_Base
  attr_accessor :spriteset
end # Scene_Map < Scene_Base

class Game_Interpreter
  def refresh_layers
    SceneManager.scene.spriteset.refresh_layers
  end

  def layer(map,id,array)
    need_refresh = false
    $game_map.layers[map] ||= []
    need_refresh = true if $game_map.layers[map][id].nil?
    $game_map.layers[map][id] = array
  end
  def del_layer(map,id)
    return if !$game_map.layers[map]
    $game_map.layers[map][id] = nil
    SceneManager.scene.spriteset.refresh_layers
  end
  def layer_status(status)
    $game_map.layer_status = status
    SceneManager.scene.spriteset.refresh_layers
  end

  def blayer(id,array)
    need_refresh = false
    $game_map.blayers ||= []
    need_refresh = true if $game_map.blayers[id].nil?
    $game_map.blayers[id] = array
  end
  def del_blayer(id)
    return if !$game_map.blayers
    $game_map.blayers[id] = nil
    SceneManager.scene.spriteset.refresh_layers if SceneManager.scene_is?(Scene_Battle)
  end

end # Game_Interpreter

class Layer_Graphic < Plane
  def initialize(viewport,id)
    super(viewport)
    @id = id
    if SceneManager.scene_is?(Scene_Battle)
      @layers = $game_map.blayers
    else
      @layers = $game_map.layers[$game_map.map_id]
    end
    @layers
    init_settings
  end

  def init_settings
    @name = @layers[@id][0]  # filename
    self.bitmap = Cache.layers(@name)
    @width = self.bitmap.width
    @height = self.bitmap.height
    if @layers[0] && @layers[0][@id]
      @movedx = @layers[0][@id][0].to_f  # stored x
      @movedy = @layers[0][@id][1].to_f  # stored y
    else
      @movedx = 0.to_f
      @movedy = 0.to_f
    end
  end

  def update
    change_graphic if @name != @layers[@id][0]
    update_opacity
    update_movement
  end

  def change_graphic
    @name = @layers[@id][0]
    self.bitmap = Cache.layers(@name)
    @width = self.bitmap.width
    @height = self.bitmap.height
  end

  def update_movement
    self.ox = 0 + $game_map.display_x * 32 + @movedx + xoffset
    self.oy = 0 + $game_map.display_y * 32 + @movedy + yoffset
    @movedx += @layers[@id][1]
    @movedy += @layers[@id][2]
    @movedx = 0 if @movedx >= @width
    @movedy = 0 if @movedy >= @height
    self.z = @layers[@id][4]
    self.blend_type = @layers[@id][5]
  end

  def xoffset
    $game_map.display_x * @layers[@id][6]
  end
  def yoffset
    $game_map.display_y * @layers[@id][7]
  end

  def update_opacity
    self.opacity = @layers[@id][3]
  end

  def dispose
    $game_map.layers[0][@id] = [@movedx,@movedy]
    self.bitmap.dispose if self.bitmap
    super
  end
end # Layer_Graphic < Plane

16 thoughts on “Galv’s Layer Graphics V.1.3

  1. Talemaster says:

    Script have a error:
    def yoffset
    $game_map.display_x * @layers[@id][7]
    end
    and must be:
    def yoffset
    $game_map.display_y * @layers[@id][7]
    end

    Player walk in side but the parallax move up and down. Everything else it’s good, thank’s for the script)

  2. shatsumori says:

    It always seems to be telling me, that it doesn’t find the file in Graphics/Layers, even though it’s clearly there. Even when changing absolutely nothing from one project where it works (or the demo that is) to another, while also using the exact same script commands, it just throws an error even though the file is in that exact location, it’s frustrating, really.

    • Galv says:

      It’s frustrating, really, when people come here to complain and don’t supply any information that would help me help them or even ask nicely for help.

      If the rpgmaker error is telling you that it cannot find a file in a certain location, first thing comes to mind is that the file is not in that location.

      – Make sure you are putting the files in the right place.
      – Make sure the filename is exactly the same
      – Make sure it’s a file that rpgmaker supports.

      • shatsumori says:

        It was not my intention to complain, nor to insult you. I’m terribly sorry if it appeared that way. I was very tired when I wrote that yesterday (it was like, 1 AM here) and I didn’t realise I was being that offensive… Let me try again, I hope you can forgive my rudeness earlier.

        First things first, here is the image, present in Graphics/Layers:

        Here’s the event, calling the method:

        And here’s the exact error screen it’s given me:

        Now as for additional information, the Event is running in a parallel process, starts as soon as the game begins, so the error is immediately after starting up, I don’t use a save file, it occurs on a new game.

        Again, please, I did not mean to be rude, nor to offend you… I feel like a terrible person right now. If there’s any other information I could provide you with, I’d be glad to do so. Thanks for considering to help me out!

  3. Galv says:

    I have never seen the error you get appear if the file exists. Make sure you are editing the same project that you placed the files in (Project1). Make sure you dont have multiple Project1 folders and you’re placing the files in a different one.

    I have not encountered anything else that cause this error other than files not actually being there.

    • shatsumori says:

      Oddly enough, it appears that my secondary hard drive messed something up. I just copied the whole project into the main one, C: and it appears to be working now. Really, really weird. Anyway, thanks for your extremely quick help, I really appreciate it! Also, sorry for my behaviour yesterday again.

  4. jayraygames says:

    I had created a similar script in RMXP called ELSA, but with that being said, this script is SO much more than I would have expected. Awesome script! This appears to be independant of events, which is awesome, but I have a question/request

    Do you think there’d be a way other than event graphics to have it act as though the images ARE event-like, as in you can go in front of it with characters, behind it, as it’s acting like a regular character sprite?

    But no, seriously, awesome script I love it!

  5. Basic Leader says:

    Hi Galv! Awesome script as usual!!! I was messing around with the script to add the zoom option to my layers (the same zoom_x and zoom_y options you get when using “move picture”) and I miraculously managed to get it working by replacing your definitions of xoffset and yoffset like so:

    def xoffset
    self.zoom_x = @layers[@id][8] / 100.0
    @target_zoom_x = zoom_x.to_f
    end
    def yoffset
    self.zoom_y= @layers[@id][9] / 100.0
    @target_zoom_y = zoom_y.to_f
    end

    But doing this, I obviously lost the xoffset and y offset options, so I tried this way:

    def xoffset
    $game_map.display_x * @layers[@id][6]
    end
    def yoffset
    $game_map.display_y * @layers[@id][7]
    end

    def zoom_x
    self.zoom_x = @layers[@id][8] / 100.0
    @target_zoom_x = zoom_x.to_f
    end

    def zoom_y
    self.zoom_y= @layers[@id][9] / 100.0
    @target_zoom_y = zoom_y.to_f
    end

    And I used a script call looking like this:

    layer(1,0,[“test”,0,0,255,0,0,0,0,150,150])
    refresh_layers

    But this time, the zoom option is gone! :(
    If you don’t mind pointing me in the right direction to add this option to your script!!! Thank you very much!!!
    I’ll be trying on my side too!

    • Galv says:

      Sorry, man – I dont have time for requests. :(

      • Basic Leader says:

        That’s ok! I’ll surely learn something about scripting (I’m no scripter at all but the help file of Ace have taught me a few stuffs to play around with) by playing around with this challenge! Thanks anyway =)

      • Basic Leader says:

        In the end, I ended up using your xoffset and yoffset’s definitions as recipients for the xoffset/yoffset option AND the zoomx/zoomy, no errors but I don’t have much guarantee as far as compability goes hahaha^^ Anyway, I don’t use much scripts so it’s okay for my use.

        I also implemented the possibility to change opacity through time/duration instead of instantly (I think I took and modified a piece of one of Hime’s script to add the option to yours) and it is working well until now.

        I have used it for very interesting opacity changes on my moving clouds shadows layer, works like a charm! Thanks a lot for the simplicity of use of your awesome script! I need to make a scene in which I make use of of the zoom option to see if it can be usable!!!

        Thanks again Galv!

  6. akainoru says:

    Hello ! Nice script, exactly what I was looking for !
    You may don’t care anymore about any issue report anymore, but it can be useful for other people if I’m not the last on RPGVXace so here it is :
    I have a parallel process event with among others a “refresh_layers” and when the save menu opens from an event for instance you talk to a magical object on the map that open save menu, I had the issue “Script ‘Game_Interpreter’ line 1411:NoMethodError occurred. undefined method ‘spriteset’ for #”
    Maybe it’s my fault in the beginning or something, but it seems to be fixed by adding “if SceneManager.scene_is?(Scene_Map) || SceneManager.scene_is?(Scene_Battle)” conditions for every “SceneManager.scene.spriteset.refresh_layers” lines in “class Game_Interpreter” from this script (map and battle for methods “refresh_layers” and “layer_status” and only map for method “del_layer”, maybe it’s too much cause I didn’t completely read the full script)

    sorry for my English if ever

    have good day everyone

    • Galv says:

      Don’t use refresh layers in a parallel process. It only needs to be run if the layer didn’t previously exist. Create the layer first and have layer options in a parallel process but don’t refresh the layers in one

      • akainoru says:

        ooooh ! Thank you I misunderstand “When setting a NEW layer on the CURRENT map” silly of me. Thank also for answering, that’s very nice of you

Leave a comment