Class: AdventureRL::Layer

Inherits:
Mask show all
Includes:
Helpers::Error, Modifiers::Inventory
Defined in:
lib/AdventureRL/Layer.rb

Overview

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.

Direct Known Subclasses

Menu

Constant Summary collapse

DEFAULT_SETTINGS =

Default settings. settings passed to #new take precedence.

Settings.new(
  scale: {
    x: 1,
    y: 1
  },
  rotation: 0,
  has_solids_manager: false,
  solids_manager: {
    use_cache: false
  },
  position: {
    x: 0,
    y: 0
  },
  size: {
    width:  360,
    height: 360
  },
  origin: {
    x: :left,
    y: :top
  }
)
MASK_ID =
:mask

Constants included from Modifiers::Inventory

Modifiers::Inventory::DEFAULT_INVENTORY_ID

Constants included from Helpers::Error

Helpers::Error::PADDING, Helpers::Error::STACK_TRACE_PADDING, Helpers::Error::STACK_TRACE_SIZE

Constants inherited from Mask

Mask::MASKS

Constants inherited from Point

Point::POINTS

Instance Method Summary collapse

Methods included from Modifiers::Inventory

#added_object?, #get_object, #get_objects, #remove_object, #remove_objects, #removed

Methods included from Helpers::Error

directory_exists?, error, error_no_directory, error_no_file, file_exists?

Methods inherited from Mask

#assign_to, #assigned_to?, #collides_with?, #collides_with_hash?, #collides_with_mask?, #collides_with_point?, #get_assigned, #get_center, #get_corner, #get_layer, #get_mask, #get_origin, #get_real_center, #get_real_corner, #get_real_side, #get_real_sides, #get_side, #get_sides, #get_size, #has_layer?, #has_mask?, #set_layer, #set_size

Methods inherited from Point

#assign_to, #assigned_to?, #collides_with?, #collides_with_hash?, #collides_with_mask?, #collides_with_point?, #get_assigned, #get_layer, #get_point, #get_position, #get_real_position, #has_layer?, #has_point?, #keys, #set_layer, #set_position, #values, #x, #y

Constructor Details

#initialize(settings = {}) ⇒ Layer

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



41
42
43
44
45
46
47
48
# 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

Instance Method Details

#add_object(object, id = nil) ⇒ Object Also known as: add_item, add, <<

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



53
54
55
56
57
58
# 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

#drawObject

Call this every frame. This draws all its inventory objects (its children), if they have a #draw method.



202
203
204
205
206
207
208
209
210
211
# 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_pointObject

Returns a new Point with this Layers real window position.



142
143
144
145
146
147
148
149
150
151
# 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) ⇒ Object

Returns the real scale of this Layer. That is, this Layer’s scale multiplied by all parent Layer’s scales.



74
75
76
77
78
79
80
81
82
# 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_rotationObject

Returns the current rotation.



115
116
117
# File 'lib/AdventureRL/Layer.rb', line 115

def get_rotation
  return @rotation
end

#get_scale(target = :all) ⇒ Object

Returns the current scale. target can be either :x, :y, or :all.



65
66
67
68
69
# 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_managerObject

Returns a SolidsManager, if it has one.



159
160
161
162
163
# 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?Boolean

Returns true if this Layer has a SolidsManager.

Returns:

  • (Boolean)


154
155
156
# 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) ⇒ Object

Increase (or decrease) the layer rotation. Pass an angle as an Integer or Float.



132
133
134
135
136
137
138
139
# 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) ⇒ Object

Increase (or decrease) the layer scaling by an amount. Pass an axis, either :x or :y, and an amount as an Integer or Float.



102
103
104
105
106
107
108
109
110
111
112
# 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) ⇒ Object

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.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# 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) ⇒ Object

Set the layer rotation. Pass an angle as an Integer or Float.



121
122
123
124
125
126
127
128
# 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) ⇒ Object

Set the layer scaling. Pass an axis, either :x or :y, and an amount as an Integer or Float.



87
88
89
90
91
92
93
94
95
96
97
# 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

#updateObject

Call this every frame. This updates all its inventory objects (its children), if they have an #update method.



194
195
196
197
# File 'lib/AdventureRL/Layer.rb', line 194

def update
  call_method_on_children :update
  get_solids_manager.update  if (has_solids_manager?)
end