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.

BDR Layer v1.3

BDR Layer Version: 1.3 for RMVX
By: Fustel

Introduction
This script allow the display of multiple maps in a single map scene. The extra map are considered layers shown over the base map.
The best usage I found for it, and for naw, is the show/hide building roofs, while preserving what is inside the building. This is not a redrawing of the building interior. This is 'really' a multi-layered map.

Features
  • Multi-layered maps
  • Show / Hide each layer individually or as a whole
  • Select the layer management method
  • Make all the changes now, or ready them for the next map to load

Screenshots

with a roof


without a roof

Demo
http://www.mediafire.com/?z8rs8ocl6uuhgom

Look at the cool & quick roof removal when you enter a hut.
And now, don't hesitate to go down the cellar...

Script
[rgss]#==============================================================================
# ** BDR Layer
#------------------------------------------------------------------------------
#  © Fustel, 2010
#  26/05/10
#  Version 1.2
#------------------------------------------------------------------------------
#  VERSION HISTORY:
#   - 1.0 (26/05/10): Initial release
#   - 1.1 (15/06/10): allows usage of small / big layers and their positioning
#   - 1.2 (05/11/10): corrected bug when reloading a previos map
#                     allows hide_layer & show_layer method without parametes
#                       to hide/show all layers
#                     allows the setting of the layer management method
#   - 1.3 (24/01/11): dynamically (script) select the displayrd layers for the next map
#                     dynamically (script) select the display method
#                     method can alos be set to take effect only on next map
#                     bugs fixed
#                       - save / load visibility flag
#                       - bad display at first graphic update when
#                         returning from a scene (menu & others...)
#--------------------------------------------------------------------------------
#  INSTRUCTIONS:
#   - Place this script in the 'Materials' section
#   - Create layers as sub-maps. They may be of any size
#   - Link layers to the main map (see CONFIGURATION below)
#-------------------------------------------------------------------------------
# CONFIGURATION
#  - Update the BDR::Layer::Layer constant
#    - key  = base map ID
#    - data = [ [ layer ID (MUST be unique)
#                 layer map ID
#                 layer viewport z value (height)
#                 layer visible at start (true/false)
#                 (optional, default=0) X position of layer in main map
#                 (optional, default=0) Y position of layer in main map
#               ]
#               , ...
#             ]
#
#  - If necessary, update the BDR::Layer::Method constant for the default method
#    - 1 for viewport repositionning
#    - 2 for viewport offset
#    - 3 for tilemep  offset
#-------------------------------------------------------------------------------
# USAGE (provinding $scene is a Scene_Map)
#  - show a layer :
#      $scene.show_layer(<layer ID>)
#  - show all layers :
#      $scene.show_layer
#  - hide a layer :
#      $scene.hide_layer(<layer ID>)
#  - hide all layers :
#      $scene.hide_layer
#  - change the layer being displayed when entering next map
#    (only listed layer are shown) :
#      $scene.show_layers_on_next_map([<layer_ids>])
#  - change the display method
#      $game_system.bdr_layer_method = <n>
#  - set the display method for next map
#      $game_sustem.bdr_layer_method_on_next_map = <n>
#-------------------------------------------------------------------------------
# NOTE
#  - about the z value of the layer viewport, remomber
#    - special effects(weather, pictures) are at z = 50
#    - the scene brightness is at z = 100
#  - For still unknown reasons, the original viowport repositioning layer
#      management method didn't seem to work for some projects. After multiple
#      experiments , I decided to provide the 3 managements methods that I
#      imagined. If one of them doesn't go well with your project, please try
#      the other ones, and report.
#-------------------------------------------------------------------------------
 
module BDR
  module Layer
    # 1 = viewport reposionning
    # 2 = viewport offset
    # 3 = tilemap  offset
    #--------------------------
    Method = 1
 
    # key  = map ID
    # data = [ [ layer ID,
    #            layer map ID,
    #            viewport z value,
    #            visible at start (true/false),
    #            (optional) layer X position in main map (default = 0),
    #            (optional) layer Y position in main map (default = 0)
    #          ],
    #          ...
    #        ]
    #---------------------------------------
    Layer = {}
    Layer[1] = [ [ 1, 2, 1, true,  4, 2],   # left hut roof
                 [ 2, 2, 1, true, 14, 2]]   # right hut roof
 
    Layer[3] = [ [ 1, 4, 2, false],
                 [ 2, 5, 2, false],
                 [ 3, 6, 2, false]]
  end
end
 
class Game_Temp
  attr_accessor :bdr_layer_show_on_next_map
end
 
class Game_System
  attr_accessor :bdr_layer_method_on_next_map
 
  def bdr_layer_method
    return BDR::Layer::Method if @bdr_layer_method == nil
    return @bdr_layer_method
  end
 
  def bdr_layer_method=(value)
    @bdr_layer_method = value if [1,2,3].include?(value)
  end
 
  def bdr_layer_visible
    @bdr_layer_visible = {} if @bdr_layer_visible == nil
    return @bdr_layer_visible if @bdr_layer_map_id == $game_map.map_id
    @bdr_layer_map_id = $game_map.map_id
    @bdr_layer_visible = {}
    layers = BDR::Layer::Layer[ @bdr_layer_map_id]
    return @bdr_layer_visible if layers == nil
    for layer in layers
      @bdr_layer_visible[ layer[ 0]] = layer[ 3]
    end
    return @bdr_layer_visible if $game_temp.bdr_layer_show_on_next_map == nil
    for id in @bdr_layer_visible.keys
      @bdr_layer_visible[ id] = $game_temp.bdr_layer_show_on_next_map.include?( id)
    end
    $game_temp.bdr_layer_show_on_next_map = nil
    return @bdr_layer_visible
  end
end
 
class Game_Map
  attr_reader :bdr_layers
 
  alias bdr_layer_initialize initialize
  def initialize
    @bdr_layers = {}
    bdr_layer_initialize
  end
 
  alias bdr_layer_setup setup
  def setup(map_id)
    @bdr_layers = {}
    bdr_layer_setup( map_id)
    $game_system.bdr_layer_method = $game_system.bdr_layer_method_on_next_map if $game_system.bdr_layer_method_on_next_map != nil
    $game_system.bdr_layer_method_on_next_map = nil
    layers = BDR::Layer::Layer[ map_id]
    layers = [] if layers == nil
    for layer in layers
      lid = layer[ 0]
      @bdr_layers[ lid] = layer.clone
      @bdr_layers[ lid][1] = load_data(sprintf("Data/Map%03d.rvdata", layer[ 1]))
      @bdr_layers[ lid][4] = 0 if layer[4] == nil
      @bdr_layers[ lid][5] = 0 if layer[5] == nil
    end
  end
end
 
class Spriteset_BDR_Layer
  def initialize( layer)
    @id = layer[ 0]
    @pos_x = layer[ 4] * 32
    @pos_y = layer[ 5] * 32
    create_viewport( layer)
    create_tilemap( layer)
    refresh
  end
 
  def create_viewport( layer)
    @viewport = Viewport.new( @pos_x, @pos_y, layer[1].width * 32, layer[1].height * 32)
    @viewport.z = layer[ 2]
  end
 
  def create_tilemap( layer)
    @tilemap = Tilemap.new(@viewport)
    @tilemap.bitmaps[0] = Cache.system("TileA1")
    @tilemap.bitmaps[1] = Cache.system("TileA2")
    @tilemap.bitmaps[2] = Cache.system("TileA3")
    @tilemap.bitmaps[3] = Cache.system("TileA4")
    @tilemap.bitmaps[4] = Cache.system("TileA5")
    @tilemap.bitmaps[5] = Cache.system("TileB")
    @tilemap.bitmaps[6] = Cache.system("TileC")
    @tilemap.bitmaps[7] = Cache.system("TileD")
    @tilemap.bitmaps[8] = Cache.system("TileE")
    @tilemap.map_data = layer[ 1].data
    @tilemap.passages = $data_system.passages
  end
 
  def dispose
    dispose_tilemap
    dispose_viewport
  end
 
  def dispose_tilemap
    @tilemap.dispose
  end
 
  def dispose_viewport
    @viewport.dispose
  end
 
  def refresh
    update_viewport
    update_tilemap
  end
 
  def update
    refresh
  end
 
  def update_tilemap
    return unless self.visible
    @tilemap.ox = $game_map.display_x / 8 + $game_map.screen.shake if $game_system.bdr_layer_method == 3
    @tilemap.oy = $game_map.display_y / 8 if $game_system.bdr_layer_method == 3
    @tilemap.update
  end
 
  def update_viewport
    @viewport.visible = $game_system.bdr_layer_visible[ @id]
    if !self.visible
      @viewport.update
      return
    end
    @viewport.tone = $game_map.screen.tone
    @viewport.rect.x = @pos_x - $game_map.display_x / 8 + $game_map.screen.shake if $game_system.bdr_layer_method == 1
    @viewport.rect.y = @pos_y - $game_map.display_y / 8 if $game_system.bdr_layer_method == 1
    @viewport.ox = $game_map.display_x / 8 + $game_map.screen.shake if $game_system.bdr_layer_method == 2
    @viewport.oy = $game_map.display_y / 8 if $game_system.bdr_layer_method == 2
    @viewport.update
  end
 
  def visible
    return @viewport.visible
  end
 
  def visible=( value)
    $game_system.bdr_layer_visible[ @id] = value
    refresh
  end
 
  def show
    self.visible = true
  end
 
  def hide
    self.visible = false
  end
end
 
class Spriteset_Map
  alias bdr_layer_initialize initialize
  def initialize
    @bdr_layers = {}
    bdr_layer_initialize
    for layer in $game_map.bdr_layers.values
      @bdr_layers[ layer[ 0]] = Spriteset_BDR_Layer.new( layer)
    end
  end
 
  alias bdr_layer_dispose dispose
  def dispose
    for layer in @bdr_layers.values
      layer.dispose
    end
    bdr_layer_dispose
  end
 
  alias bdr_layer_update update
  def update
    bdr_layer_update
    for layer in @bdr_layers.values
      layer.update
    end
  end
 
  def show_layer( id=nil)
    if id == nil
      for layer in @bdr_layers.values
        layer.show
      end
    else
      layer = @bdr_layers[ id]
      layer.show if layer != nil
   end
  end
 
  def hide_layer( id=nil)
    if id == nil
      for layer in @bdr_layers.values
        layer.hide
      end
    else
      layer = @bdr_layers[ id]
      layer.hide if layer != nil
   end
  end
end
 
class Scene_Map < Scene_Base
  def show_layer( id=nil)
    @spriteset.show_layer( id)
  end
 
  def hide_layer( id=nil)
    @spriteset.hide_layer( id)
  end
 
  def show_layers_on_next_map( layers_id)
    $game_temp.bdr_layer_show_on_next_map = layers_id
  end
end
 
[/rgss]

Instructions
  • Copy the script in the 'Materials' section, as it fully overwrite the main methods
  • Create layers for your base maps. Each layer may be any size, and generally includes many transparent tiles
  • Link base map and layer map through the BDR::Layer::Layer constant. This constant is a hash with the following structure
    • key = base map ID
    • data = array of arrays. each sub-array defines a layer with the following structure
      • [0] = layer ID (used for show/hide and future features). MUST be unique
      • [1] = layer map ID.
      • [2] = layer z value. The higher this value, the closer to the player the layer is. Remeber the following:
        • Base map is at z=0
        • Special effects (weathe, pictures, etc...) are at z=50
        • Map brightness is at z*100
      • [3] = visibility of the layer at map loading time (true / false)
      • [4] (optional, default=0) X position of layer map in main map
      • [5] (optional, default=0) Y position of layer map in main map
  • Set the default layer management method, if necessary through the BDR::Layer::Method constant
    • 1 = Viewport repositionning (the default one in the script)
    • 2 = Viewport offset
    • 3 = Tilemap offset
  • Show a layer by invoking: '$scene.show_layer(<layer ID>)
  • Show all layers by invoking: '$scene.show_layer
  • Hide a layer by invoking: '$scene.hide_layer(<layer ID>)
  • Hide all layers by invoking: '$scene.hide_layer
  • Prepare layers to be displayed on next map by invoking (only listed layers will be visible): '$scene.show_layers_on_next_map([<layer_ids>])'
  • Change the display method with: '$game_system.bdr_layer_method = <n>'
  • Set the display method for the next map with: '$game_sustem.bdr_layer_method_on_next_map = <n>'


FAQ

Compatibility
No issue known.

Credits and Thanks
All done by myself
Also, if I remember well, Dargor was working on something similar called 'Map Layers'; but I couldn't dind the reference.

Author's Notes
This is the first step to a full layered map, with player transition from layer to layer, each beeing a 'real map', not just a display thing.
It is intended as a test; so use & abuse it, and tell me if yoy nitice any stress (CPU, meory, internal ressource).

v1.1
The layer maps need not anymore to be the same size as the base map.
Technically, the viewport is now re-positioned instead of the tilemap.

v1.2
  • Corrected a bug when reentering a map with layers
  • Allow the showing/hiding of all layers in a single call
  • Introduced the management method

v1.3
  • dynamically (script) select the displayrd layers for the next map
  • dynamically (script) select the display method
  • method can alos be set to take effect only on next map
  • bugs fixed
    • save / load visibility flag
    • bad display at first graphic update when returning from a scene (menu & others...)

Terms and Conditions
You may not use this in a commercial game without my explicit permission.
You may not post this script anywhere without my explict permission.
You must give me credit.
 
The roof example reminded me about a solution for that very same problem I tried to find once... I ended up having pictures that dispose themselves when the person walks underneath them, essentially creating an almost entirely automated (obviously, you need to initialize the images) handler of self-hiding roofs. I think it's resource-friendlier than your method on the system side... of course you get relatively more filesize (I thought about having kind of an auto-roof creation from tiled pictures, which would downright minimize the filesize to not a bit more), however, I never got around to do it.
EDIT: It's also transparency-compatible ^^

But yeah... I don't want to create the impression that this script is for roofs only... I especially see the purpose in circumventing VX' donkey default mapping possibilities. I doubt it'll get more people to use VX though, sadly...

So, let's skip to the suggestion part... your scripting is comparatively outstanding, even though there's the totally undistinguishable 'BDR' in there everywhere... other than that, practical suggestions:
- handling the map layers via map names would be more confident in my opinion... it should be perfectly possible and would ease working with layers greatly.
- supporting smaller maps to overlay bigger maps would be pretty handy... especially for stuff like that hut, where a 17x13 map is perfectly sufficient in theory. Now I don't know for sure how much trouble that means, but in theory, it should be as easy as shifting the layers by x*32 and y*32 pixels, while x and y are either in your array, if you keep it, or in the map name.

I thought Ihad some more, but I either forgot them while writing this or overestimated my improvement suggestions XD

Keep up the good work!
 
BlueScope":axp2qcu2 said:
....even though there's the totally undistinguishable 'BDR' in there everywhere..
I don't know why.... but I was expecting this one.... :wink:

BlueScope":axp2qcu2 said:
- handling the map layers via map names would be more confident in my opinion... it should be perfectly possible and would ease working with layers greatly.
Map name are more often changed than map ID. Think about maintainance.

BlueScope":axp2qcu2 said:
- supporting smaller maps to overlay bigger maps would be pretty handy... especially for stuff like that hut, where a 17x13 map is perfectly sufficient in theory. Now I don't know for sure how much trouble that means, but in theory, it should be as easy as shifting the layers by x*32 and y*32 pixels, while x and y are either in your array, if you keep it, or in the map name.
Already tried it.... but a smaller map repeats drawing itself over and over the bigger one. It is hard-voded in the Tilemap class for, I think, map looping management.
Unless I also do something about the viewport....mmm...no, that mean we also have to manage the viewport position during update... forget it. Layer map HAVE to be the same size as the base map... for now...

As I said, roof management is only one the things we can do with layers. And this is only the first step to something else....
 
Well, you put the BDR there, so take it! :haha:

As for the map name, I think you misunderstood me... I don't mean store the maps by name instead of ID in the script (that indeed would be pretty stupid to do, agreed) - I mean put the layering management in the map name. Something like this:
Code:
Super-Town [34|2]
That translates to "Super-Town is the second layer for the 34th map set" - assuming you don't plan on using the seperate maps as, well, seperate maps, but only in the corresponding packages (but I think your current script assumes that as well).
After writing the following paragraph (yay time travelling), I realize it's probably better to include the map IDs of the map to layer in the base map's name. I'd elaborate further, but you're a pretty smart guy, so you should be able to figure it out... and also, work is over for today... yay freetime! ^^

And yeah, the repeating issue you talked about sounds a bit like in-the-way... however, a Tilemap rewrite should solve it, no? I remember looking for some, but couldn't find any... maybe that's changed in the meantime, but if not, it'd be a good reason (for you XD ) to make one, right? ^^ I really think it'd be worth trying to fiddle with it... (think resource weight reduced, reusuability, ...)
 
Including the layers in the map name sitll doesn't apeal to me.
  • It means the name have a meaning (not semantically acceptable)
  • It means parsing the name... and I don't like parsing name, especially with multiple parameters for each layer
  • Try & imagine a HUD displaying the map name...

As for the smaller map usage. Tilemap, although it have a Ruby interface, is a built-in class; and if you explain me how to rewrite a built-in class, I'd be eager to do it :tongue:
I also imagined (during my 'weight-management-time' :blush: ) a way to use viewport sizing & positioning. But I am not sure of whait it will do with looping map, and especially with the Player navigating from layer to layer (THIS is the big idea...).
So, for now, I keep the 'layer MUST be the same size as the base map' principle.
 
Yeah, I see where you're coming from in all points...

Regarding the Tilemap rewrite, I know it's a built-in class and therefore written in C. That doesn't mean, however, that you can't simply recreate it in Ruby, as in start with class Tilemap; end and go from there, trying to get all methods you need rewritten. Not knowing what they're called is arguably a difficulty, but as it's been done for RMXP a few times, you should be able to get an idea from there... even though they hardly have anything in common.
 
In fact, I know at least ONE thing they have not in common. VX Tilemap gors directly to the hardware, while XP used standard Windows canvas. I know this becouse my magnifying software (you know I am near-blind, didn't you) enlarges XP windowed game, but not VX one.
And moreover, I am ABSOLUTELY a C-unlover... I am one of those old-time Pascal & Delphi-er :heart:

Someone ???
 
Fustel":35otrolr said:
This scrit allow the display of multiple maps...

Sorry, but this is the one thing about this post that bugs me. If it's supposed to be a script, then well done. Fantastic. If it's a scrit, then I'm not sure what to think if it. I've never heard of a scirt.

~Its a typo, everyone makes them and in no way warrants that kind of behavior.
 
Chalupa":fqlro3v8 said:
Fustel":fqlro3v8 said:
This scrit allow the display of multiple maps...

Sorry, but this is the one thing about this post that bugs me. If it's supposed to be a script, then well done. Fantastic. If it's a scrit, then I'm not sure what to think if it. I've never heard of a scirt.


What kind of choice do I have but to answer..... Ooops... :blush:
 
Due to unanimous plebicite, as well as to the fact the (soon-to-be-released ???) full multi-layered map won't have exactly the same structure as this restricted layered one, v1.1 is up.

The only upgrade (but not the least) is about the layer size. You can now make layers of ANY size. Not the base map one anymore.

Enjoy.
 
Back to BDR Layer....
Trying to use it in a new project, a couple of issues appear.

1/ The nned to hide/show all layers in one call. This is done with show_layer and, hide_layer, without any argument.
2/ An ENORMOUS bug when re-entering a map with layers. This is corrected.
3/ An annoying issue for which I still do not have any precise explanation. It just happened the method I used to manage the layers (moving its Viewport around) doen't work in this project. After some experiments, I implement a nex method, using the Viewport offset. Which in turn didn't work with the demo. Thus I implemented the 3 methods I found, allowing everybody to choose which one to use. But if anyone has a clear explanation about Viewport.rect, Viewport.ox (and oy) and Tilemap.ox (and oy), PLEEAAASSSSEEEE enlight us.....
 
After using and abusing the script myself (in a grant vintage project soon to come...), I noticesd some bugs & flaws that are corected in this version. See the Notes and Instructions on the may post for more details
 

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