class AdventureRL::Layer
This class is supposed to be a sort of container for instances which have Mask
s assigned to them. It can manipulate any drawing operations, which will effect all Mask
s contained. See Gosu methods. Layer
also has a Mask
.
Constants
- DEFAULT_SETTINGS
Default settings.
settings
passed to new take precedence.- MASK_ID
Public Class Methods
Initialize Layer
with a settings
Hash. See DEFAULT_SETTINGS
for valid keys.
AdventureRL::Modifiers::Inventory::new
# File lib/AdventureRL/Layer.rb, line 41 def initialize settings = {} @settings = DEFAULT_SETTINGS.merge settings @scale = @settings.get :scale @rotation = @settings.get :rotation @has_solids_manager = !!@settings.get(:has_solids_manager) @solids_manager = SolidsManager.new if (has_solids_manager?) super @settings #.get.reject { |key,val| next key == :assign_to } end
Public Instance Methods
Add any object to this Layer
. Pass an optional id
, which can be used to access or remove the object afterwards.
AdventureRL::Modifiers::Inventory#add_object
# File lib/AdventureRL/Layer.rb, line 53 def add_object object, id = nil id = MASK_ID if (id.nil? && object.is_a?(Mask)) id ||= DEFAULT_INVENTORY_ID super object, id object.set_layer self if (object.methods.include?(:set_layer) || object_mask_has_method?(object, :set_layer)) end
Call this every frame. This draws all its inventory objects (its children), if they have a draw
method.
# File lib/AdventureRL/Layer.rb, line 202 def draw Gosu.scale(@scale[:x], @scale[:y], x, y) do Gosu.rotate(@rotation, *get_center.values) do Gosu.translate(*get_corner(:left, :top).get_position.values) do call_method_on_children :draw end #draw_debug # TODO: Clean up end end end
Returns a new Point
with this Layers real window position.
# File lib/AdventureRL/Layer.rb, line 142 def get_real_point pos_x = x * get_scale(:x) pos_y = y * get_scale(:y) return Point.new(pos_x, pos_y) unless (has_layer?) real_point = get_layer.get_real_point return Point.new( (real_point.x + pos_x), (real_point.y + pos_y) ) end
Returns the real scale of this Layer
. That is, this Layer's scale multiplied by all parent Layer's scales.
# File lib/AdventureRL/Layer.rb, line 74 def get_real_scale target = :all return get_scale target unless (has_layer?) return get_layer.get_real_scale(target) * get_scale(target) if (@scale.key? target) return { x: (get_layer.get_real_scale(:x) * get_scale(:x)), y: (get_layer.get_real_scale(:y) * get_scale(:y)) } if (target == :all) return nil end
Returns the current rotation.
# File lib/AdventureRL/Layer.rb, line 115 def get_rotation return @rotation end
Returns the current scale. target
can be either :x
, :y
, or :all
.
# File lib/AdventureRL/Layer.rb, line 65 def get_scale target = :all return @scale[target] if (@scale.key? target) return @scale if (target == :all) return nil end
Returns a SolidsManager
, if it has one.
# File lib/AdventureRL/Layer.rb, line 159 def get_solids_manager return @solids_manager if (@solids_manager) return get_layer.get_solids_manager if (has_layer?) return nil end
Returns true
if this Layer
has a SolidsManager
.
# File lib/AdventureRL/Layer.rb, line 154 def has_solids_manager? return @has_solids_manager || (has_layer? ? get_layer.has_solids_manager? : false) end
Increase (or decrease) the layer rotation. Pass an angle
as an Integer or Float.
# File lib/AdventureRL/Layer.rb, line 132 def increase_rotation angle error( "Passed argument `angle' needs to be an Integer or Float, but got", " #{angle.inspect}.#{angle.class.name}" ) unless ([Integer, Float].include? angle.class) @rotation += angle handle_rotation_overflow end
Increase (or decrease) the layer scaling by an amount
. Pass an axis
, either :x
or :y
, and an amount
as an Integer or Float.
# File lib/AdventureRL/Layer.rb, line 102 def increase_scale axis, amount error( "Passed argument `axis' needs to be one of the following:", " #{@scale.keys.map(&:inspect).join(', ')}" ) unless (@scale.key? axis) error( "Passed argument `amount' needs to be an Integer or Float, but got", " #{amount.inspect}.#{amount.class.name}" ) unless ([Integer, Float].include? amount.class) @scale[axis] += amount if (@scale.key? axis) end
Overwrite the method Point#move_by
, so we can also call move_by
on all Mask
children. We use a little hacky workaround, by moving all children back the amount of incremental movement, then move this Layer
forward, and then move all the children Masks via move_by
.
# File lib/AdventureRL/Layer.rb, line 170 def move_by *args incremental_position = parse_position(*args) incremental_position[:x] ||= 0 incremental_position[:y] ||= 0 objects = get_objects.select do |object| next object.is_a?(Mask) end # Move all children Masks back via #set_position. objects.each do |mask| mask.set_position( (mask.x - incremental_position[:x]), (mask.y - incremental_position[:y]) ) end super # Move Layer forward # Move all children Masks forward via #move_by. objects.each do |mask| mask.move_by incremental_position end end
Set the layer rotation. Pass an angle
as an Integer or Float.
# File lib/AdventureRL/Layer.rb, line 121 def set_rotation angle error( "Passed argument `angle' needs to be an Integer or Float, but got", " #{angle.inspect}.#{angle.class.name}" ) unless ([Integer, Float].include? angle.class) @rotation = angle handle_rotation_overflow end
Set the layer scaling. Pass an axis
, either :x
or :y
, and an amount
as an Integer or Float.
# File lib/AdventureRL/Layer.rb, line 87 def set_scale axis, amount error( "Passed argument `axis' needs to be one of the following:", " #{@scale.keys.map(&:inspect).join(', ')}" ) unless (@scale.key? axis) error( "Passed argument `amount' needs to be an Integer or Float, but got", " #{amount.inspect}.#{amount.class.name}" ) unless ([Integer, Float].include? amount.class) @scale[axis] = amount end
Call this every frame. This updates all its inventory objects (its children), if they have an update
method.
# File lib/AdventureRL/Layer.rb, line 194 def update call_method_on_children :update get_solids_manager.update if (has_solids_manager?) end
Private Instance Methods
# File lib/AdventureRL/Layer.rb, line 238 def call_method_on_children method_name, *args get_objects.each do |child| meth = nil if (child.methods.include?(method_name)) meth = child.method(method_name) elsif (object_mask_has_method?(child, method_name)) meth = child.get_mask.method(method_name) end meth.call(*args) if (meth) end end
# File lib/AdventureRL/Layer.rb, line 215 def draw_debug # Top Gosu.draw_line( *get_corner(:left, :top).values, 0xff_ff0000, *get_corner(:right, :top).values, 0xff_ff0000 ) # Right Gosu.draw_line( *get_corner(:right, :top).values, 0xff_ff0000, *get_corner(:right, :bottom).values, 0xff_ff0000, ) # Bottom Gosu.draw_line( *get_corner(:right, :bottom).values, 0xff_ff0000, *get_corner(:left, :bottom).values, 0xff_ff0000, ) # Left Gosu.draw_line( *get_corner(:left, :bottom).values, 0xff_ff0000, *get_corner(:left, :top).values, 0xff_ff0000, ) end
# File lib/AdventureRL/Layer.rb, line 266 def handle_rotation_overflow return if ((0 ... 360).include? @rotation) @rotation -= 360 if (@rotation >= 360) @rotation += 360 if (@rotation < 0) handle_rotation_overflow end
# File lib/AdventureRL/Layer.rb, line 257 def object_has_mask? object begin object.has_mask? rescue NoMethodError return false end return true end
# File lib/AdventureRL/Layer.rb, line 250 def object_mask_has_method? object, method_name return ( object_has_mask?(object) && object.get_mask.methods.include?(method_name) ) end