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

new(settings = {}) click to toggle source

Initialize Layer with a settings Hash. See DEFAULT_SETTINGS for valid keys.

Calls superclass method 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

<<(object, id = nil)
Alias for: add_object
add(object, id = nil)
Alias for: add_object
add_item(object, id = nil)
Alias for: add_object
add_object(object, id = nil) click to toggle source

Add any object to this Layer. Pass an optional id, which can be used to access or remove the object afterwards.

# 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
Also aliased as: add_item, add, <<
draw() click to toggle source

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
get_real_point() click to toggle source

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
get_real_scale(target = :all) click to toggle source

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
get_rotation() click to toggle source

Returns the current rotation.

# File lib/AdventureRL/Layer.rb, line 115
def get_rotation
  return @rotation
end
get_scale(target = :all) click to toggle source

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
get_solids_manager() click to toggle source

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
has_solids_manager?() click to toggle source

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_rotation(angle) click to toggle source

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_scale(axis, amount) click to toggle source

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
move_by(*args) click to toggle source

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.

Calls superclass method
# 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_rotation(angle) click to toggle source

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_scale(axis, amount) click to toggle source

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
update() click to toggle source

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

call_method_on_children(method_name, *args) click to toggle source
# 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
draw_debug() click to toggle source
# 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
handle_rotation_overflow() click to toggle source
# 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
object_has_mask?(object) click to toggle source
# File lib/AdventureRL/Layer.rb, line 257
def object_has_mask? object
  begin
    object.has_mask?
  rescue NoMethodError
    return false
  end
  return true
end
object_mask_has_method?(object, method_name) click to toggle source
# 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