Class: Zif::Layers::LayerGroup
- Inherits:
-
Object
- Object
- Zif::Layers::LayerGroup
- Includes:
- Traceable
- Defined in:
- lib/zif/layers/layer_group.rb
Overview
Designed to be used with Camera.
Creates a set of overlapping play area layers based on SimpleLayer (RenderTarget) or ActiveLayer (CompoundSprite) and handles redrawing them.
Has a concept of logical
position as a multiple of tile
width/height, applicable to any Tileable layers. For example, if your tiles are 16px wide, the 5th tile is at @logical_x==4 but at @x==64 on the layer.
Of all things in the Zif library, this is probably the most opinionated - It’s for a 2d game made of rectangular, non-overlapping tiles where the play area is larger than the screen. As always YMMV
As an example, you can have a “tiles” layer which gets redrawn only at the start of the game, an “interactive objects” layer which gets redrawn whenever objects appear or disappear, and then an “avatar” layer which gets redrawn constantly. The advantage of using RenderTargets and CompoundSprites here is to keep the positioning consistent across all of the layers. You can just pass all of the containing sprites to Camera and it will pan them all in unison.
You setup and configure these layers via #new_simple_layer, #new_tiled_layer, etc.
Performance notes:
-
The memory requirements for anything based on SimpleLayer is the number of layers times the area of each layer. Consider using ActiveLayer if you have a lot of layers with few sprites in them.
-
It is expensive to redraw a RenderTarget (SimpleLayer) with thousands of sprites. Consider: 1280x720 (screen size) / 16x16 (a small tile) -> 80*45 tiles = 3600 tiles. Of course it’s more expensive to draw every tile every tick (using ActiveLayer), but you will see noticable hiccups if you redraw the render target often. Try not to redraw RenderTargets with lots of sprites while action is happening.
-
The takeaway is this: try to organize your layers between things that change often, and things that can be prerendered or need few updates duing play. Then choose between SimpleLayer and ActiveLayer as appropriate.
Instance Attribute Summary collapse
-
#layers ⇒ Hash<(Symbol, String), Zif::Layers::Layerable>
All of the layers in this group, indexed by their name.
-
#logical_height ⇒ Integer
Integer multiple of tiles.
-
#logical_width ⇒ Integer
Integer multiple of tiles.
-
#name ⇒ Symbol, String
The name of the layer group.
-
#tile_height ⇒ Integer
Pixel height of each tile.
-
#tile_width ⇒ Integer
Pixel width of each tile.
-
#z_index ⇒ Integer
readonly
The current stacking layer index.
Attributes included from Traceable
Instance Method Summary collapse
-
#add_layer(name, layer) ⇒ Zif::Layers::Layerable
Adds a layer to the layer group.
-
#force_refresh ⇒ Object
Iterate through each in #layers, set
should_render
to true, rerender, and set it back to what it was Useful for first-time setup of render targets, during init. -
#initialize(name: 'map', tile_width: 64, tile_height: 64, logical_width: 100, logical_height: 100) ⇒ LayerGroup
constructor
A new instance of LayerGroup.
- #inspect ⇒ Object
-
#layer_containing_sprites ⇒ Array<Zif::Sprite>
The containing sprite for each layer.
-
#layer_names ⇒ Array<Symbol, String>
The names of each registered layer.
-
#logical_pos(x, y) ⇒ Array<Integer>
Converts pixel x/y to logical x/y (rounded down).
-
#max_height ⇒ Integer
#tile_height times #logical_height.
-
#max_width ⇒ Integer
#tile_width times #logical_width.
-
#natural_rect(logical_x, logical_y, x_range, y_range) ⇒ Array<Integer>
Converts a
logical
rect to a natural one. -
#new_active_bitmasked_tiled_layer(name) ⇒ Zif::Layers::ActiveBitmaskedTiledLayer
Creates a new ActiveBitmaskedTiledLayer and sends it through #add_layer.
-
#new_active_layer(name) ⇒ Zif::Layers::ActiveLayer
Creates a new ActiveLayer and sends it through #add_layer.
-
#new_active_tiled_layer(name) ⇒ Zif::Layers::ActiveTiledLayer
Creates a new ActiveTiledLayer and sends it through #add_layer.
-
#new_bitmasked_tiled_layer(name, render_only_visible: false) ⇒ Zif::Layers::BitmaskedTiledLayer
Creates a new BitmaskedTiledLayer and sends it through #add_layer.
-
#new_simple_layer(name, render_only_visible: false, clear_sprites_after_draw: false) ⇒ Zif::Layers::SimpleLayer
Creates a new SimpleLayer and sends it through #add_layer.
-
#new_tiled_layer(name, render_only_visible: false) ⇒ Zif::Layers::TiledLayer
Creates a new TiledLayer and sends it through #add_layer.
-
#refresh ⇒ Object
Calls
#rerender
on each in #layers. - #serialize ⇒ Object
- #to_s ⇒ Object
Methods included from Traceable
#mark, #mark_and_print, #mark_prefix, #tracer
Constructor Details
#initialize(name: 'map', tile_width: 64, tile_height: 64, logical_width: 100, logical_height: 100) ⇒ LayerGroup
Returns a new instance of LayerGroup.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/zif/layers/layer_group.rb', line 91 def initialize(name: 'map', tile_width: 64, tile_height: 64, logical_width: 100, logical_height: 100) @name = name @tile_width = tile_width @tile_height = tile_height @logical_width = logical_width @logical_height = logical_height @z_index = 0 @layers = {} @tracer_service_name = :tracer end |
Instance Attribute Details
#layers ⇒ Hash<(Symbol, String), Zif::Layers::Layerable>
Returns All of the layers in this group, indexed by their name.
84 85 86 |
# File 'lib/zif/layers/layer_group.rb', line 84 def layers @layers end |
#logical_height ⇒ Integer
Returns Integer multiple of tiles. How many tiles high is the whole map?.
80 81 82 |
# File 'lib/zif/layers/layer_group.rb', line 80 def logical_height @logical_height end |
#logical_width ⇒ Integer
Returns Integer multiple of tiles. How many tiles wide is the whole map?.
78 79 80 |
# File 'lib/zif/layers/layer_group.rb', line 78 def logical_width @logical_width end |
#name ⇒ Symbol, String
Returns The name of the layer group.
72 73 74 |
# File 'lib/zif/layers/layer_group.rb', line 72 def name @name end |
#tile_height ⇒ Integer
Returns Pixel height of each tile.
76 77 78 |
# File 'lib/zif/layers/layer_group.rb', line 76 def tile_height @tile_height end |
#tile_width ⇒ Integer
Returns Pixel width of each tile.
74 75 76 |
# File 'lib/zif/layers/layer_group.rb', line 74 def tile_width @tile_width end |
#z_index ⇒ Integer (readonly)
Returns The current stacking layer index. Starts at 0
and is incremented for every new layer.
82 83 84 |
# File 'lib/zif/layers/layer_group.rb', line 82 def z_index @z_index end |
Instance Method Details
#add_layer(name, layer) ⇒ Zif::Layers::Layerable
110 111 112 113 114 |
# File 'lib/zif/layers/layer_group.rb', line 110 def add_layer(name, layer) @layers[name] = layer @z_index += 1 return @layers[name] end |
#force_refresh ⇒ Object
Iterate through each in #layers, set should_render
to true, rerender, and set it back to what it was Useful for first-time setup of render targets, during init
219 220 221 222 223 224 225 226 |
# File 'lib/zif/layers/layer_group.rb', line 219 def force_refresh @layers.each do |_name, layer| render_setting = layer.should_render layer.should_render = true layer.rerender layer.should_render = render_setting end end |
#inspect ⇒ Object
263 264 265 |
# File 'lib/zif/layers/layer_group.rb', line 263 def inspect serialize.to_s end |
#layer_containing_sprites ⇒ Array<Zif::Sprite>
Returns The containing sprite for each layer. For active layers this returns the layer itself For simple layers it returns the render target containing_sprite.
236 237 238 |
# File 'lib/zif/layers/layer_group.rb', line 236 def layer_containing_sprites @layers.values.map(&:containing_sprite) end |
#layer_names ⇒ Array<Symbol, String>
Returns The names of each registered layer.
229 230 231 |
# File 'lib/zif/layers/layer_group.rb', line 229 def layer_names @layers.keys end |
#logical_pos(x, y) ⇒ Array<Integer>
Converts pixel x/y to logical x/y (rounded down)
210 211 212 213 214 215 |
# File 'lib/zif/layers/layer_group.rb', line 210 def logical_pos(x, y) [ (x / @tile_width).floor, (y / @tile_height).floor ] end |
#max_height ⇒ Integer
Returns #tile_height times #logical_height.
183 184 185 |
# File 'lib/zif/layers/layer_group.rb', line 183 def max_height @tile_height * @logical_height end |
#max_width ⇒ Integer
Returns #tile_width times #logical_width.
178 179 180 |
# File 'lib/zif/layers/layer_group.rb', line 178 def max_width @tile_width * @logical_width end |
#natural_rect(logical_x, logical_y, x_range, y_range) ⇒ Array<Integer>
Converts a logical
rect to a natural one
195 196 197 198 199 200 201 202 |
# File 'lib/zif/layers/layer_group.rb', line 195 def natural_rect(logical_x, logical_y, x_range, y_range) [ logical_x * @tile_width, logical_y * @tile_width, x_range * @tile_width, y_range * @tile_width ] end |
#new_active_bitmasked_tiled_layer(name) ⇒ Zif::Layers::ActiveBitmaskedTiledLayer
Creates a new ActiveBitmaskedTiledLayer and sends it through #add_layer
173 174 175 |
# File 'lib/zif/layers/layer_group.rb', line 173 def new_active_bitmasked_tiled_layer(name) add_layer(name, Zif::Layers::ActiveBitmaskedTiledLayer.new(self, name, z_index: @z_index)) end |
#new_active_layer(name) ⇒ Zif::Layers::ActiveLayer
Creates a new ActiveLayer and sends it through #add_layer
119 120 121 |
# File 'lib/zif/layers/layer_group.rb', line 119 def new_active_layer(name) add_layer(name, Zif::Layers::ActiveLayer.new(self, name, z_index: @z_index)) end |
#new_active_tiled_layer(name) ⇒ Zif::Layers::ActiveTiledLayer
Creates a new ActiveTiledLayer and sends it through #add_layer
155 156 157 |
# File 'lib/zif/layers/layer_group.rb', line 155 def new_active_tiled_layer(name) add_layer(name, Zif::Layers::ActiveTiledLayer.new(self, name, z_index: @z_index)) end |
#new_bitmasked_tiled_layer(name, render_only_visible: false) ⇒ Zif::Layers::BitmaskedTiledLayer
Creates a new BitmaskedTiledLayer and sends it through #add_layer
163 164 165 166 167 168 |
# File 'lib/zif/layers/layer_group.rb', line 163 def new_bitmasked_tiled_layer(name, render_only_visible: false) add_layer( name, Zif::Layers::BitmaskedTiledLayer.new(self, name, z_index: @z_index, render_only_visible: render_only_visible) ) end |
#new_simple_layer(name, render_only_visible: false, clear_sprites_after_draw: false) ⇒ Zif::Layers::SimpleLayer
Creates a new SimpleLayer and sends it through #add_layer
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/zif/layers/layer_group.rb', line 128 def new_simple_layer(name, render_only_visible: false, clear_sprites_after_draw: false) add_layer( name, Zif::Layers::SimpleLayer.new( self, name, z_index: @z_index, render_only_visible: render_only_visible, clear_sprites_after_draw: clear_sprites_after_draw ) ) end |
#new_tiled_layer(name, render_only_visible: false) ⇒ Zif::Layers::TiledLayer
Creates a new TiledLayer and sends it through #add_layer
145 146 147 148 149 150 |
# File 'lib/zif/layers/layer_group.rb', line 145 def new_tiled_layer(name, render_only_visible: false) add_layer( name, Zif::Layers::TiledLayer.new(self, name, z_index: @z_index, render_only_visible: render_only_visible) ) end |
#refresh ⇒ Object
Calls #rerender
on each in #layers
241 242 243 244 245 246 247 248 249 |
# File 'lib/zif/layers/layer_group.rb', line 241 def refresh @layers.each do |layer_name, layer| mark("#refresh: Rerendering #{layer_name}") layer.rerender mark("#refresh: Rerendered #{layer_name}") end mark('#refresh: Rerendered all layers') end |
#serialize ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/zif/layers/layer_group.rb', line 251 def serialize { name: name, tile_width: tile_width, tile_height: tile_height, logical_width: logical_width, logical_height: logical_height, z_index: z_index, layers: layers.keys } end |
#to_s ⇒ Object
267 268 269 |
# File 'lib/zif/layers/layer_group.rb', line 267 def to_s serialize.to_s end |