Class: Gosling::Actor
- Includes:
- Transformable
- Defined in:
- lib/gosling/actor.rb
Overview
Actors are fundamental elements of a rendering and worldspace hierarchy. They represent the things that exist inside of the game world or parts of our application’s user interface.
A key difference between an Actor and any of its subclasses - Circle, Polygon, Sprite, and the like - is that an Actor is inherently intangible. By itself, it has no shape or appearance and takes up no space. If it’s something you can see or interact with, it should probably be an instance of one of Actor’s subclasses.
The inheritance model is what makes an Actor by itself useful. Actors can have one or more children, which can be any type of Actor. Those Actors can in turn have any number of child Actors, and so on, creating a sort of tree structure. A parent Actor’s transform is inherited by its children, so moving or rotating a parent Actor moves or rotates all of its children relative to its parent. And when a parent is drawn, all of its children are drawn as well (see #draw for exceptions).
One common application of this is to use a plain Actor as a root object to which all other elements visible in the game world are added. As the player moves through the game world, rather than move the position of each game element across the screen to simulate travel, you need only move the root Actor and all other Actors will be moved similarly. This root actor then acts like a “stage” or “camera”. For this reason, one could think of a plain Actor as sort of a “container” for other Actors, a way to keep them all organized and related.
The behavior of inheritance can modified by setting various properties. Read on for more details.
Instance Attribute Summary collapse
-
#are_children_tangible ⇒ Object
If set to true, this Actor’s children will respond to “point-in-shape” tests.
-
#are_children_visible ⇒ Object
If set to true, all of this Actor’s children will be drawn to screen.
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#color ⇒ Object
The Gosu::Color to use when rendering this Actor.
-
#is_mask ⇒ Object
If set to true, this Actor will be treated as a “mask” for its parent regarding “point-in-shape” tests.
-
#is_tangible ⇒ Object
If set to true, this Actor will respond to “point-in-shape” tests.
-
#is_visible ⇒ Object
If set to true, this Actor will be drawn to screen.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#window ⇒ Object
readonly
Returns the value of attribute window.
Attributes included from Transformable
Instance Method Summary collapse
-
#add_child(child) ⇒ Object
Establishes a parent/child relationship between this actor and the one passed, respectively.
-
#alpha ⇒ Object
Wrapper method.
-
#alpha=(val) ⇒ Object
Wrapper method.
-
#blue ⇒ Object
Wrapper method.
-
#blue=(val) ⇒ Object
Wrapper method.
-
#draw(matrix = nil) ⇒ Object
Calls #render on this Actor, drawing it to the screen if #is_visible is set to true (the default).
-
#get_actor_at(point) ⇒ Object
Given a point in global space, tests this Actor and each of its children, returning the first Actor for whom this point is inside its shape.
-
#get_actors_at(point) ⇒ Object
Functions similarly to #get_actor_at, but returns a list of
all
Actors for whom the point is inside their shape. -
#get_global_position(out = nil) ⇒ Object
Returns the global x/y position of this actor (where it is relative to its root ancestor).
-
#get_global_transform(out = nil) ⇒ Object
Returns a Snow::Mat3 transformation matrix combining this Actor’s transforms as well as all of its ancestors.
-
#green ⇒ Object
Wrapper method.
-
#green=(val) ⇒ Object
Wrapper method.
-
#has_child?(child) ⇒ Boolean
Returns true if this Actor has the given Actor as a child.
-
#initialize(window) ⇒ Actor
constructor
Creates a new Actor, setting all inheritance properties to their defaults and assigning a random color.
- #inspect ⇒ Object
-
#is_point_in_bounds(point) ⇒ Object
Returns false.
-
#red ⇒ Object
Wrapper method.
-
#red=(val) ⇒ Object
Wrapper method.
-
#remove_child(child) ⇒ Object
If the given Actor is a child of this Actor, it is disassociated from this Actor.
Methods included from Transformable
#center, #center=, #center_x, #center_x=, #center_y, #center_y=, #reset, #scale, #scale=, #scale_x, #scale_x=, #scale_y, #scale_y=, #to_matrix, transform_point, #transform_point, #translation, #translation=, untransform_point, #untransform_point, #x, #x=, #y, #y=
Constructor Details
#initialize(window) ⇒ Actor
Creates a new Actor, setting all inheritance properties to their defaults and assigning a random color. Requires a Gosu::Window to be used when rendering.
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/gosling/actor.rb', line 72 def initialize(window) super() @window = window @parent = nil @children = [] @is_visible = true @is_tangible = true @are_children_visible = true @are_children_tangible = true @is_mask = false @color = Gosu::Color.from_hsv(rand(360), rand(), rand()) end |
Instance Attribute Details
#are_children_tangible ⇒ Object
If set to true, this Actor’s children will respond to “point-in-shape” tests. If false, such tests will skip them and their descendants. The default is true.
54 55 56 |
# File 'lib/gosling/actor.rb', line 54 def are_children_tangible @are_children_tangible end |
#are_children_visible ⇒ Object
If set to true, all of this Actor’s children will be drawn to screen. If false, they and their descendants will be skipped. The default is true.
48 49 50 |
# File 'lib/gosling/actor.rb', line 48 def are_children_visible @are_children_visible end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
31 32 33 |
# File 'lib/gosling/actor.rb', line 31 def children @children end |
#color ⇒ Object
The Gosu::Color to use when rendering this Actor.
66 67 68 |
# File 'lib/gosling/actor.rb', line 66 def color @color end |
#is_mask ⇒ Object
If set to true, this Actor will be treated as a “mask” for its parent regarding “point-in-shape” tests. If the point is in this Actor’s bounds, it will act as though the point is in its parent’s bounds instead of its own. The default is false.
61 62 63 |
# File 'lib/gosling/actor.rb', line 61 def is_mask @is_mask end |
#is_tangible ⇒ Object
If set to true, this Actor will respond to “point-in-shape” tests. If false, such tests will skip this Actor. The default is true.
42 43 44 |
# File 'lib/gosling/actor.rb', line 42 def is_tangible @is_tangible end |
#is_visible ⇒ Object
If set to true, this Actor will be drawn to screen. If false, it will be skipped. The default is true.
36 37 38 |
# File 'lib/gosling/actor.rb', line 36 def is_visible @is_visible end |
#parent ⇒ Object
Returns the value of attribute parent.
31 32 33 |
# File 'lib/gosling/actor.rb', line 31 def parent @parent end |
#window ⇒ Object (readonly)
Returns the value of attribute window.
31 32 33 |
# File 'lib/gosling/actor.rb', line 31 def window @window end |
Instance Method Details
#add_child(child) ⇒ Object
Establishes a parent/child relationship between this actor and the one passed, respectively. The child Actor will appear relative to its parent, move as the parent moves, and draw when the parent draws.
An Actor cannot be made a child of itself. Similarly, a child cannot be added to a parent if doing so would create a circular reference (e.g. a.add_child(b) followed by b.add_child(a)).
If the child Actor already had a parent, the Actor is disassociated from its former parent before becoming associated with this one. An Actor can have only one parent at a time.
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/gosling/actor.rb', line 99 def add_child(child) return if @children.include?(child) raise Gosling::InheritanceError.new("An Actor cannot be made a child of itself.") if child == self ancestor = parent until ancestor.nil? raise Gosling::InheritanceError.new("Adding a child's ancestor as a child would create a circular reference.") if child == ancestor ancestor = ancestor.parent end child.parent.remove_child(child) if child.parent @children.push(child) child.parent = self end |
#alpha ⇒ Object
Wrapper method. Returns this Actor’s alpha value (0-255).
243 244 245 |
# File 'lib/gosling/actor.rb', line 243 def alpha @color.alpha end |
#alpha=(val) ⇒ Object
Wrapper method. Sets this Actor’s alpha value (0-255).
250 251 252 |
# File 'lib/gosling/actor.rb', line 250 def alpha=(val) @color.alpha = val end |
#blue ⇒ Object
Wrapper method. Returns this Actor’s blue value (0-255).
285 286 287 |
# File 'lib/gosling/actor.rb', line 285 def blue @color.blue end |
#blue=(val) ⇒ Object
Wrapper method. Sets this Actor’s blue value (0-255).
292 293 294 |
# File 'lib/gosling/actor.rb', line 292 def blue=(val) @color.blue = val end |
#draw(matrix = nil) ⇒ Object
Calls #render on this Actor, drawing it to the screen if #is_visible is set to true (the default).
The Actor’s transforms, if any, will be applied prior to rendering. If an optional Snow::Mat3 matrix transform is given, the Actor will be transformed by a combination of that matrix transform and its own.
If the #are_children_visible flag is set to true (the default), then this method will recursively call draw on each of the Actor’s children, passing them the combined matrix used to render the parent. Otherwise, children will be skipped and not drawn.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/gosling/actor.rb', line 141 def draw(matrix = nil) transform = MatrixCache.instance.get if matrix to_matrix.multiply(matrix, transform) else transform.set(to_matrix) end render(transform) if @is_visible if @are_children_visible @children.each { |child| child.draw(transform) } end ensure MatrixCache.instance.recycle(transform) end |
#get_actor_at(point) ⇒ Object
Given a point in global space, tests this Actor and each of its children, returning the first Actor for whom this point is inside its shape. Respects each Actor’s transforms as well as any it may inherit from its ancestors. Useful for determining which Actor the user may have clicked on.
If the #is_tangible flag is set to false, this Actor will not be tested. The default is true.
If the #are_children_tangible flag is set to false, this Actor’s children will not be tested. The default is true.
If the #is_mask flag is set to true, a positive test from this Actor instead returns its parent Actor, if any. The default is false.
If the point is not inside this Actor or any of its children (excluding any skipped Actors), nil is returned.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/gosling/actor.rb', line 179 def get_actor_at(point) hit = nil if @are_children_tangible @children.reverse_each do |child| hit = child.get_actor_at(point) if hit break if @is_mask return hit end end end hit = self if hit == nil && @is_tangible && is_point_in_bounds(point) hit = @parent if @is_mask && hit == self hit end |
#get_actors_at(point) ⇒ Object
Functions similarly to #get_actor_at, but returns a list of all
Actors for whom the point is inside their shape.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/gosling/actor.rb', line 198 def get_actors_at(point) actors = [] if @are_children_tangible @children.reverse_each do |child| actors |= child.get_actors_at(point) end end actors.push(self) if @is_tangible && is_point_in_bounds(point) actors.uniq! if @is_mask actors.map! { |actor| (actor == self) ? @parent : actor } end actors end |
#get_global_position(out = nil) ⇒ Object
Returns the global x/y position of this actor (where it is relative to its root ancestor). This value is calculated using the Actor’s center (see Transformable#center).
231 232 233 234 235 236 237 238 |
# File 'lib/gosling/actor.rb', line 231 def get_global_position(out = nil) tf = MatrixCache.instance.get get_global_transform(tf) out ||= Snow::Vec3.new Transformable.transform_point(tf, center, out) ensure MatrixCache.instance.recycle(tf) end |
#get_global_transform(out = nil) ⇒ Object
Returns a Snow::Mat3 transformation matrix combining this Actor’s transforms as well as all of its ancestors. This matrix can be used to transform a point in this Actor’s local space to its global equivalent (the geometric space of its root ancestor).
218 219 220 221 222 223 224 225 |
# File 'lib/gosling/actor.rb', line 218 def get_global_transform(out = nil) out ||= Snow::Mat3.new if parent to_matrix.multiply(parent.get_global_transform, out) else out.set(to_matrix) end end |
#green ⇒ Object
Wrapper method. Returns this Actor’s green value (0-255).
271 272 273 |
# File 'lib/gosling/actor.rb', line 271 def green @color.green end |
#green=(val) ⇒ Object
Wrapper method. Sets this Actor’s green value (0-255).
278 279 280 |
# File 'lib/gosling/actor.rb', line 278 def green=(val) @color.green = val end |
#has_child?(child) ⇒ Boolean
Returns true if this Actor has the given Actor as a child.
127 128 129 |
# File 'lib/gosling/actor.rb', line 127 def has_child?(child) @children.include?(child) end |
#inspect ⇒ Object
85 86 87 |
# File 'lib/gosling/actor.rb', line 85 def inspect "#<#{self.class}:#{self.object_id}>" end |
#is_point_in_bounds(point) ⇒ Object
Returns false. Actors have no shape, and so no point is in their bounds. Subclasses override this method with shape-specific behavior.
161 162 163 |
# File 'lib/gosling/actor.rb', line 161 def is_point_in_bounds(point) false end |
#red ⇒ Object
Wrapper method. Returns this Actor’s red value (0-255).
257 258 259 |
# File 'lib/gosling/actor.rb', line 257 def red @color.red end |
#red=(val) ⇒ Object
Wrapper method. Sets this Actor’s red value (0-255).
264 265 266 |
# File 'lib/gosling/actor.rb', line 264 def red=(val) @color.red = val end |
#remove_child(child) ⇒ Object
If the given Actor is a child of this Actor, it is disassociated from this Actor. In any case, the child Actor is immediately orphaned.
117 118 119 120 121 122 |
# File 'lib/gosling/actor.rb', line 117 def remove_child(child) return unless @children.include?(child) @children.delete(child) child.parent = nil end |