gosling 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f40ad4e1b06a4aeb3653172b748bb6b9cff0aaec
4
- data.tar.gz: '0249b7dbe396d152de3791ad3e5548ffad9c8ece'
2
+ SHA256:
3
+ metadata.gz: ac651ebce37fb5da3aacc1ced63789b6d9651c5ce8c0c112e9380e6d1ecdafd3
4
+ data.tar.gz: f3dada919c44fe16a49811bbb8e823257713e6042b858727737220f5d59f647e
5
5
  SHA512:
6
- metadata.gz: 05a6efbacdee880176e86660408c0d005d0e32e86e1eca91a213e1552dfdbccfe40edf43d167669e0684690d2280299ce49448d2f3719b7604bb037c683e6a49
7
- data.tar.gz: b5670a5dace288c80bb8ba339cbba83b171d1e0ec8d104b2ba327792e550dc4957783ec0ee710940bc45c115af4f40d958bf77563b7711b6a248fd31ed5a933b
6
+ metadata.gz: d31bf801d211beef278199b322efeda3286cebb3951cc1f23f64e063b0b87367f82bd345d1fe6bb4aaca5415afc4b315eb39d89b706261cd8cf49a42c7032283
7
+ data.tar.gz: fe40452705018052c180a3c9dd1f0b2a961347d83361ee83c0fa9c8c173043b747c632f89d12f152b10e97b28c5e155ef87ac832685477c39bc823ffe1eb7abc
data/lib/gosling.rb CHANGED
@@ -1,4 +1,4 @@
1
- Dir.glob(File.join(File.dirname(__FILE__), 'gosling/*.rb')).each { |file| require_relative file }
2
-
3
- module Gosling
4
- end
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'gosling/*.rb')).each { |file| require_relative file }
2
+
3
+ module Gosling
4
+ end
data/lib/gosling/actor.rb CHANGED
@@ -1,328 +1,328 @@
1
- require_relative 'transformable.rb'
2
-
3
- require 'gosu'
4
-
5
- module Gosling
6
- ##
7
- # Actors are fundamental elements of a rendering and worldspace hierarchy. They represent the things that exist
8
- # inside of the game world or parts of our application's user interface.
9
- #
10
- # A key difference between an Actor and any of its subclasses - Circle, Polygon, Sprite, and the like - is that an
11
- # Actor is inherently intangible. By itself, it has no shape or appearance and takes up no space. If it's something you
12
- # can see or interact with, it should probably be an instance of one of Actor's subclasses.
13
- #
14
- # The inheritance model is what makes an Actor by itself useful. Actors can have one or more children, which can be
15
- # any type of Actor. Those Actors can in turn have any number of child Actors, and so on, creating a sort of tree
16
- # structure. A parent Actor's transform is inherited by its children, so moving or rotating a parent Actor moves or
17
- # rotates all of its children relative to its parent. And when a parent is drawn, all of its children are drawn as well
18
- # (see #draw for exceptions).
19
- #
20
- # One common application of this is to use a plain Actor as a root object to which all other elements visible in the
21
- # game world are added. As the player moves through the game world, rather than move the position of each game
22
- # element across the screen to simulate travel, you need only move the root Actor and all other Actors will be moved
23
- # similarly. This root actor then acts like a "stage" or "camera". For this reason, one could think of a plain Actor as
24
- # sort of a "container" for other Actors, a way to keep them all organized and related.
25
- #
26
- # The behavior of inheritance can modified by setting various properties. Read on for more details.
27
- #
28
- class Actor
29
- include Transformable
30
-
31
- attr_reader :parent, :children, :window
32
-
33
- ##
34
- # If set to true, this Actor will be drawn to screen. If false, it will be skipped. The default is true.
35
- #
36
- attr_accessor :is_visible
37
-
38
- ##
39
- # If set to true, this Actor will respond to "point-in-shape" tests. If false, such tests will skip this Actor. The default
40
- # is true.
41
- #
42
- attr_accessor :is_tangible
43
-
44
- ##
45
- # If set to true, all of this Actor's children will be drawn to screen. If false, they and their descendants will be
46
- # skipped. The default is true.
47
- #
48
- attr_accessor :are_children_visible
49
-
50
- ##
51
- # If set to true, this Actor's children will respond to "point-in-shape" tests. If false, such tests will skip them and
52
- # their descendants. The default is true.
53
- #
54
- attr_accessor :are_children_tangible
55
-
56
- ##
57
- # If set to true, this Actor will be treated as a "mask" for its parent regarding "point-in-shape" tests. If the point is
58
- # 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
59
- # false.
60
- #
61
- attr_accessor :is_mask
62
-
63
- ##
64
- # The Gosu::Color to use when rendering this Actor.
65
- #
66
- attr_accessor :color
67
-
68
- ##
69
- # Creates a new Actor, setting all inheritance properties to their defaults and assigning a random color. Requires
70
- # a Gosu::Window to be used when rendering.
71
- #
72
- def initialize(window)
73
- super()
74
- @window = window
75
- @parent = nil
76
- @children = []
77
- @is_visible = true
78
- @is_tangible = true
79
- @are_children_visible = true
80
- @are_children_tangible = true
81
- @is_mask = false
82
- @color = Gosu::Color.from_hsv(rand(360), rand(), rand())
83
- end
84
-
85
- def inspect
86
- "#<#{self.class}:#{self.object_id}>"
87
- end
88
-
89
- ##
90
- # Establishes a parent/child relationship between this actor and the one passed, respectively. The child Actor will
91
- # appear relative to its parent, move as the parent moves, and draw when the parent draws.
92
- #
93
- # An Actor cannot be made a child of itself. Similarly, a child cannot be added to a parent if doing so would create
94
- # a circular reference (e.g. a.add_child(b) followed by b.add_child(a)).
95
- #
96
- # If the child Actor already had a parent, the Actor is disassociated from its former parent before becoming
97
- # associated with this one. An Actor can have only one parent at a time.
98
- #
99
- def add_child(child)
100
- return if @children.include?(child)
101
- raise Gosling::InheritanceError.new("An Actor cannot be made a child of itself.") if child == self
102
- ancestor = parent
103
- until ancestor.nil?
104
- raise Gosling::InheritanceError.new("Adding a child's ancestor as a child would create a circular reference.") if child == ancestor
105
- ancestor = ancestor.parent
106
- end
107
-
108
- child.parent.remove_child(child) if child.parent
109
- @children.push(child)
110
- child.parent = self
111
- end
112
-
113
- ##
114
- # If the given Actor is a child of this Actor, it is disassociated from this Actor. In any case, the child Actor is
115
- # immediately orphaned.
116
- #
117
- def remove_child(child)
118
- return unless @children.include?(child)
119
-
120
- @children.delete(child)
121
- child.parent = nil
122
- end
123
-
124
- ##
125
- # Returns true if this Actor has the given Actor as a child.
126
- #
127
- def has_child?(child)
128
- @children.include?(child)
129
- end
130
-
131
- ##
132
- # Calls #render on this Actor, drawing it to the screen if #is_visible is set to true (the default).
133
- #
134
- # The Actor's transforms, if any, will be applied prior to rendering. If an optional Snow::Mat3 matrix transform is
135
- # given, the Actor will be transformed by a combination of that matrix transform and its own.
136
- #
137
- # If the #are_children_visible flag is set to true (the default), then this method will recursively call draw on each
138
- # of the Actor's children, passing them the combined matrix used to render the parent. Otherwise, children will
139
- # be skipped and not drawn.
140
- #
141
- def draw(matrix = nil)
142
- transform = MatrixCache.instance.get
143
- if matrix
144
- to_matrix.multiply(matrix, transform)
145
- else
146
- transform.set(to_matrix)
147
- end
148
-
149
- render(transform) if @is_visible
150
- if @are_children_visible
151
- @children.each { |child| child.draw(transform) }
152
- end
153
- ensure
154
- MatrixCache.instance.recycle(transform)
155
- end
156
-
157
- ##
158
- # Returns false. Actors have no shape, and so no point is in their bounds. Subclasses override this method with
159
- # shape-specific behavior.
160
- #
161
- def is_point_in_bounds(point)
162
- false
163
- end
164
-
165
- ##
166
- # Given a point in global space, tests this Actor and each of its children, returning the first Actor for whom this
167
- # point is inside its shape. Respects each Actor's transforms as well as any it may inherit from its ancestors.
168
- # Useful for determining which Actor the user may have clicked on.
169
- #
170
- # If the #is_tangible flag is set to false, this Actor will not be tested. The default is true.
171
- #
172
- # If the #are_children_tangible flag is set to false, this Actor's children will not be tested. The default is true.
173
- #
174
- # If the #is_mask flag is set to true, a positive test from this Actor instead returns its parent Actor, if any. The
175
- # default is false.
176
- #
177
- # If the point is not inside this Actor or any of its children (excluding any skipped Actors), nil is returned.
178
- #
179
- def get_actor_at(point)
180
- hit = nil
181
- if @are_children_tangible
182
- @children.reverse_each do |child|
183
- hit = child.get_actor_at(point)
184
- if hit
185
- break if @is_mask
186
- return hit
187
- end
188
- end
189
- end
190
- hit = self if hit == nil && @is_tangible && is_point_in_bounds(point)
191
- hit = @parent if @is_mask && hit == self
192
- hit
193
- end
194
-
195
- ##
196
- # Functions similarly to #get_actor_at, but returns a list of +all+ Actors for whom the point is inside their shape.
197
- #
198
- def get_actors_at(point)
199
- actors = []
200
- if @are_children_tangible
201
- @children.reverse_each do |child|
202
- actors |= child.get_actors_at(point)
203
- end
204
- end
205
- actors.push(self) if @is_tangible && is_point_in_bounds(point)
206
- actors.uniq!
207
- if @is_mask
208
- actors.map! { |actor| (actor == self) ? @parent : actor }
209
- end
210
- actors
211
- end
212
-
213
- ##
214
- # Returns a Snow::Mat3 transformation matrix combining this Actor's transforms as well as all of its ancestors.
215
- # This matrix can be used to transform a point in this Actor's local space to its global equivalent (the geometric
216
- # space of its root ancestor).
217
- #
218
- def get_global_transform(out = nil)
219
- out ||= Snow::Mat3.new
220
- if parent
221
- to_matrix.multiply(parent.get_global_transform, out)
222
- else
223
- out.set(to_matrix)
224
- end
225
- end
226
-
227
- ##
228
- # Returns the global x/y position of this actor (where it is relative to its root ancestor). This value is calculated
229
- # using the Actor's center (see Transformable#center).
230
- #
231
- def get_global_position(out = nil)
232
- tf = MatrixCache.instance.get
233
- get_global_transform(tf)
234
- out ||= Snow::Vec3.new
235
- Transformable.transform_point(tf, center, out)
236
- ensure
237
- MatrixCache.instance.recycle(tf)
238
- end
239
-
240
- ##
241
- # Wrapper method. Returns this Actor's alpha value (0-255).
242
- #
243
- def alpha
244
- @color.alpha
245
- end
246
-
247
- ##
248
- # Wrapper method. Sets this Actor's alpha value (0-255).
249
- #
250
- def alpha=(val)
251
- @color.alpha = val
252
- end
253
-
254
- ##
255
- # Wrapper method. Returns this Actor's red value (0-255).
256
- #
257
- def red
258
- @color.red
259
- end
260
-
261
- ##
262
- # Wrapper method. Sets this Actor's red value (0-255).
263
- #
264
- def red=(val)
265
- @color.red = val
266
- end
267
-
268
- ##
269
- # Wrapper method. Returns this Actor's green value (0-255).
270
- #
271
- def green
272
- @color.green
273
- end
274
-
275
- ##
276
- # Wrapper method. Sets this Actor's green value (0-255).
277
- #
278
- def green=(val)
279
- @color.green = val
280
- end
281
-
282
- ##
283
- # Wrapper method. Returns this Actor's blue value (0-255).
284
- #
285
- def blue
286
- @color.blue
287
- end
288
-
289
- ##
290
- # Wrapper method. Sets this Actor's blue value (0-255).
291
- #
292
- def blue=(val)
293
- @color.blue = val
294
- end
295
-
296
- protected
297
-
298
- def render(matrix)
299
- end
300
-
301
- def fill_polygon(vertices)
302
- (2...vertices.length).each do |i|
303
- v0 = vertices[0]
304
- v1 = vertices[i - 1]
305
- v2 = vertices[i]
306
- @window.draw_triangle(
307
- v0[0].to_f, v0[1].to_f, @color,
308
- v1[0].to_f, v1[1].to_f, @color,
309
- v2[0].to_f, v2[1].to_f, @color,
310
- )
311
- end
312
- end
313
-
314
- ##
315
- # Internal use only. See #add_child and #remove_child.
316
- #
317
- def parent=(parent)
318
- return if parent == @parent
319
- unless parent
320
- raise Gosling::InheritanceError.new("You should use Actor.remove_child() instead of setting the parent directly.") if @parent.has_child?(self)
321
- end
322
- @parent = parent
323
- if @parent
324
- raise Gosling::InheritanceError.new("You should use Actor.add_child() instead of setting the parent directly.") unless @parent.has_child?(self)
325
- end
326
- end
327
- end
328
- end
1
+ require_relative 'transformable.rb'
2
+
3
+ require 'gosu'
4
+
5
+ module Gosling
6
+ ##
7
+ # Actors are fundamental elements of a rendering and worldspace hierarchy. They represent the things that exist
8
+ # inside of the game world or parts of our application's user interface.
9
+ #
10
+ # A key difference between an Actor and any of its subclasses - Circle, Polygon, Sprite, and the like - is that an
11
+ # Actor is inherently intangible. By itself, it has no shape or appearance and takes up no space. If it's something you
12
+ # can see or interact with, it should probably be an instance of one of Actor's subclasses.
13
+ #
14
+ # The inheritance model is what makes an Actor by itself useful. Actors can have one or more children, which can be
15
+ # any type of Actor. Those Actors can in turn have any number of child Actors, and so on, creating a sort of tree
16
+ # structure. A parent Actor's transform is inherited by its children, so moving or rotating a parent Actor moves or
17
+ # rotates all of its children relative to its parent. And when a parent is drawn, all of its children are drawn as well
18
+ # (see #draw for exceptions).
19
+ #
20
+ # One common application of this is to use a plain Actor as a root object to which all other elements visible in the
21
+ # game world are added. As the player moves through the game world, rather than move the position of each game
22
+ # element across the screen to simulate travel, you need only move the root Actor and all other Actors will be moved
23
+ # similarly. This root actor then acts like a "stage" or "camera". For this reason, one could think of a plain Actor as
24
+ # sort of a "container" for other Actors, a way to keep them all organized and related.
25
+ #
26
+ # The behavior of inheritance can modified by setting various properties. Read on for more details.
27
+ #
28
+ class Actor
29
+ include Transformable
30
+
31
+ attr_reader :parent, :children, :window
32
+
33
+ ##
34
+ # If set to true, this Actor will be drawn to screen. If false, it will be skipped. The default is true.
35
+ #
36
+ attr_accessor :is_visible
37
+
38
+ ##
39
+ # If set to true, this Actor will respond to "point-in-shape" tests. If false, such tests will skip this Actor. The default
40
+ # is true.
41
+ #
42
+ attr_accessor :is_tangible
43
+
44
+ ##
45
+ # If set to true, all of this Actor's children will be drawn to screen. If false, they and their descendants will be
46
+ # skipped. The default is true.
47
+ #
48
+ attr_accessor :are_children_visible
49
+
50
+ ##
51
+ # If set to true, this Actor's children will respond to "point-in-shape" tests. If false, such tests will skip them and
52
+ # their descendants. The default is true.
53
+ #
54
+ attr_accessor :are_children_tangible
55
+
56
+ ##
57
+ # If set to true, this Actor will be treated as a "mask" for its parent regarding "point-in-shape" tests. If the point is
58
+ # 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
59
+ # false.
60
+ #
61
+ attr_accessor :is_mask
62
+
63
+ ##
64
+ # The Gosu::Color to use when rendering this Actor.
65
+ #
66
+ attr_accessor :color
67
+
68
+ ##
69
+ # Creates a new Actor, setting all inheritance properties to their defaults and assigning a random color. Requires
70
+ # a Gosu::Window to be used when rendering.
71
+ #
72
+ def initialize(window)
73
+ super()
74
+ @window = window
75
+ @parent = nil
76
+ @children = []
77
+ @is_visible = true
78
+ @is_tangible = true
79
+ @are_children_visible = true
80
+ @are_children_tangible = true
81
+ @is_mask = false
82
+ @color = Gosu::Color.from_hsv(rand(360), rand(), rand())
83
+ end
84
+
85
+ def inspect
86
+ "#<#{self.class}:#{self.object_id}>"
87
+ end
88
+
89
+ ##
90
+ # Establishes a parent/child relationship between this actor and the one passed, respectively. The child Actor will
91
+ # appear relative to its parent, move as the parent moves, and draw when the parent draws.
92
+ #
93
+ # An Actor cannot be made a child of itself. Similarly, a child cannot be added to a parent if doing so would create
94
+ # a circular reference (e.g. a.add_child(b) followed by b.add_child(a)).
95
+ #
96
+ # If the child Actor already had a parent, the Actor is disassociated from its former parent before becoming
97
+ # associated with this one. An Actor can have only one parent at a time.
98
+ #
99
+ def add_child(child)
100
+ return if @children.include?(child)
101
+ raise Gosling::InheritanceError.new("An Actor cannot be made a child of itself.") if child == self
102
+ ancestor = parent
103
+ until ancestor.nil?
104
+ raise Gosling::InheritanceError.new("Adding a child's ancestor as a child would create a circular reference.") if child == ancestor
105
+ ancestor = ancestor.parent
106
+ end
107
+
108
+ child.parent.remove_child(child) if child.parent
109
+ @children.push(child)
110
+ child.parent = self
111
+ end
112
+
113
+ ##
114
+ # If the given Actor is a child of this Actor, it is disassociated from this Actor. In any case, the child Actor is
115
+ # immediately orphaned.
116
+ #
117
+ def remove_child(child)
118
+ return unless @children.include?(child)
119
+
120
+ @children.delete(child)
121
+ child.parent = nil
122
+ end
123
+
124
+ ##
125
+ # Returns true if this Actor has the given Actor as a child.
126
+ #
127
+ def has_child?(child)
128
+ @children.include?(child)
129
+ end
130
+
131
+ ##
132
+ # Calls #render on this Actor, drawing it to the screen if #is_visible is set to true (the default).
133
+ #
134
+ # The Actor's transforms, if any, will be applied prior to rendering. If an optional Snow::Mat3 matrix transform is
135
+ # given, the Actor will be transformed by a combination of that matrix transform and its own.
136
+ #
137
+ # If the #are_children_visible flag is set to true (the default), then this method will recursively call draw on each
138
+ # of the Actor's children, passing them the combined matrix used to render the parent. Otherwise, children will
139
+ # be skipped and not drawn.
140
+ #
141
+ def draw(matrix = nil)
142
+ transform = MatrixCache.instance.get
143
+ if matrix
144
+ to_matrix.multiply(matrix, transform)
145
+ else
146
+ transform.set(to_matrix)
147
+ end
148
+
149
+ render(transform) if @is_visible
150
+ if @are_children_visible
151
+ @children.each { |child| child.draw(transform) }
152
+ end
153
+ ensure
154
+ MatrixCache.instance.recycle(transform)
155
+ end
156
+
157
+ ##
158
+ # Returns false. Actors have no shape, and so no point is in their bounds. Subclasses override this method with
159
+ # shape-specific behavior.
160
+ #
161
+ def is_point_in_bounds(point)
162
+ false
163
+ end
164
+
165
+ ##
166
+ # Given a point in global space, tests this Actor and each of its children, returning the first Actor for whom this
167
+ # point is inside its shape. Respects each Actor's transforms as well as any it may inherit from its ancestors.
168
+ # Useful for determining which Actor the user may have clicked on.
169
+ #
170
+ # If the #is_tangible flag is set to false, this Actor will not be tested. The default is true.
171
+ #
172
+ # If the #are_children_tangible flag is set to false, this Actor's children will not be tested. The default is true.
173
+ #
174
+ # If the #is_mask flag is set to true, a positive test from this Actor instead returns its parent Actor, if any. The
175
+ # default is false.
176
+ #
177
+ # If the point is not inside this Actor or any of its children (excluding any skipped Actors), nil is returned.
178
+ #
179
+ def get_actor_at(point)
180
+ hit = nil
181
+ if @are_children_tangible
182
+ @children.reverse_each do |child|
183
+ hit = child.get_actor_at(point)
184
+ if hit
185
+ break if @is_mask
186
+ return hit
187
+ end
188
+ end
189
+ end
190
+ hit = self if hit == nil && @is_tangible && is_point_in_bounds(point)
191
+ hit = @parent if @is_mask && hit == self
192
+ hit
193
+ end
194
+
195
+ ##
196
+ # Functions similarly to #get_actor_at, but returns a list of +all+ Actors for whom the point is inside their shape.
197
+ #
198
+ def get_actors_at(point)
199
+ actors = []
200
+ if @are_children_tangible
201
+ @children.reverse_each do |child|
202
+ actors |= child.get_actors_at(point)
203
+ end
204
+ end
205
+ actors.push(self) if @is_tangible && is_point_in_bounds(point)
206
+ actors.uniq!
207
+ if @is_mask
208
+ actors.map! { |actor| (actor == self) ? @parent : actor }
209
+ end
210
+ actors
211
+ end
212
+
213
+ ##
214
+ # Returns a Snow::Mat3 transformation matrix combining this Actor's transforms as well as all of its ancestors.
215
+ # This matrix can be used to transform a point in this Actor's local space to its global equivalent (the geometric
216
+ # space of its root ancestor).
217
+ #
218
+ def get_global_transform(out = nil)
219
+ out ||= Snow::Mat3.new
220
+ if parent
221
+ to_matrix.multiply(parent.get_global_transform, out)
222
+ else
223
+ out.set(to_matrix)
224
+ end
225
+ end
226
+
227
+ ##
228
+ # Returns the global x/y position of this actor (where it is relative to its root ancestor). This value is calculated
229
+ # using the Actor's center (see Transformable#center).
230
+ #
231
+ def get_global_position(out = nil)
232
+ tf = MatrixCache.instance.get
233
+ get_global_transform(tf)
234
+ out ||= Snow::Vec3.new
235
+ Transformable.transform_point(tf, center, out)
236
+ ensure
237
+ MatrixCache.instance.recycle(tf)
238
+ end
239
+
240
+ ##
241
+ # Wrapper method. Returns this Actor's alpha value (0-255).
242
+ #
243
+ def alpha
244
+ @color.alpha
245
+ end
246
+
247
+ ##
248
+ # Wrapper method. Sets this Actor's alpha value (0-255).
249
+ #
250
+ def alpha=(val)
251
+ @color.alpha = val
252
+ end
253
+
254
+ ##
255
+ # Wrapper method. Returns this Actor's red value (0-255).
256
+ #
257
+ def red
258
+ @color.red
259
+ end
260
+
261
+ ##
262
+ # Wrapper method. Sets this Actor's red value (0-255).
263
+ #
264
+ def red=(val)
265
+ @color.red = val
266
+ end
267
+
268
+ ##
269
+ # Wrapper method. Returns this Actor's green value (0-255).
270
+ #
271
+ def green
272
+ @color.green
273
+ end
274
+
275
+ ##
276
+ # Wrapper method. Sets this Actor's green value (0-255).
277
+ #
278
+ def green=(val)
279
+ @color.green = val
280
+ end
281
+
282
+ ##
283
+ # Wrapper method. Returns this Actor's blue value (0-255).
284
+ #
285
+ def blue
286
+ @color.blue
287
+ end
288
+
289
+ ##
290
+ # Wrapper method. Sets this Actor's blue value (0-255).
291
+ #
292
+ def blue=(val)
293
+ @color.blue = val
294
+ end
295
+
296
+ protected
297
+
298
+ def render(matrix)
299
+ end
300
+
301
+ def fill_polygon(vertices)
302
+ (2...vertices.length).each do |i|
303
+ v0 = vertices[0]
304
+ v1 = vertices[i - 1]
305
+ v2 = vertices[i]
306
+ @window.draw_triangle(
307
+ v0[0].to_f, v0[1].to_f, @color,
308
+ v1[0].to_f, v1[1].to_f, @color,
309
+ v2[0].to_f, v2[1].to_f, @color,
310
+ )
311
+ end
312
+ end
313
+
314
+ ##
315
+ # Internal use only. See #add_child and #remove_child.
316
+ #
317
+ def parent=(parent)
318
+ return if parent == @parent
319
+ unless parent
320
+ raise Gosling::InheritanceError.new("You should use Actor.remove_child() instead of setting the parent directly.") if @parent.has_child?(self)
321
+ end
322
+ @parent = parent
323
+ if @parent
324
+ raise Gosling::InheritanceError.new("You should use Actor.add_child() instead of setting the parent directly.") unless @parent.has_child?(self)
325
+ end
326
+ end
327
+ end
328
+ end