rubygoo 0.0.3 → 0.0.4

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.
@@ -1,40 +1,39 @@
1
- class Dialog < Container
1
+ module Rubygoo
2
+ class Dialog < Container
3
+
4
+ def initialize(opts, &close_callback)
5
+ super opts
6
+ @close_callback = close_callback if block_given?
7
+ @modal_target = opts[:modal]
8
+ end
9
+
10
+ def added()
11
+ super
12
+
13
+ @bg_color = theme_property :bg_color
14
+ @color = theme_property :color
15
+
16
+ @border_color = theme_property :border_color
17
+ @focus_color = theme_property :focus_color
18
+
19
+ @rect = Rect.new [@x-@x_pad,@y-@y_pad,@w+2*@x_pad,@h+2*@y_pad]
20
+ end
21
+
22
+ # show the dialog by adding it to the @modal_target and
23
+ # intercepting all of its events
24
+ def show()
25
+ @modal_target.add_modal self
26
+ end
27
+
28
+ # def on_mouse_dragging(x,y,event); end
29
+ # def on_mouse_motion(event); end
30
+ # def on_mouse_drag(start_x, start_y, event); end
31
+ # def on_click(event); end
32
+ # def on_key_up(event); end
33
+ # def draw(destination); end
34
+ # def on_network(event); end
35
+ # def update(time);end
2
36
 
3
- def initialize(opts, &close_callback)
4
- super opts
5
- @close_callback = close_callback if block_given?
6
- @modal_target = opts[:modal]
7
37
  end
8
-
9
- def added()
10
- super
11
- font = theme_property :font
12
- font_size = theme_property :font_size
13
- @font = TTF.new(File.join(@app.theme_dir,font), font_size)
14
-
15
- @bg_color = theme_property :bg_color
16
- @color = theme_property :color
17
-
18
- @border_color = theme_property :border_color
19
- @focus_color = theme_property :focus_color
20
-
21
- @rect = Rect.new [@x-@x_pad,@y-@y_pad,@w+2*@x_pad,@h+2*@y_pad]
22
- end
23
-
24
- # show the dialog by adding it to the @modal_target and
25
- # intercepting all of its events
26
- def show()
27
- @modal_target.add_modal self
28
- end
29
-
30
- # def on_mouse_dragging(x,y,event); end
31
- # def on_mouse_motion(event); end
32
- # def on_mouse_drag(start_x, start_y, event); end
33
- # def on_click(event); end
34
- # def on_key_up(event); end
35
- # def draw(destination); end
36
- # def on_network(event); end
37
- # def update(time);end
38
-
39
38
  end
40
39
 
@@ -1,8 +1,16 @@
1
- # is an rbga color
2
- class GooColor
3
- attr_accessor :r,:g,:b,:a
4
- def initialize(r,g,b,a)
5
- @r,@g,@b,@a = r,g,b,a
6
- end
1
+ require 'css_colors'
2
+ module Rubygoo
3
+ # is an rbga color
4
+ class GooColor
5
+ attr_accessor :r,:g,:b,:a
6
+ def initialize(r,g,b,a)
7
+ @r,@g,@b,@a = r,g,b,a
8
+ end
7
9
 
10
+ def self.css_color(sym, alpha=nil)
11
+ color = CSS_COLORS[sym]
12
+ a = alpha.nil? ? color[3] : alpha
13
+ GooColor.new color[0], color[1], color[2], a
14
+ end
15
+ end
8
16
  end
@@ -1,11 +1,13 @@
1
- # all events in the system are converted to these for internal use by our
2
- # adapter
3
- class GooEvent
4
- attr_accessor :event_type, :data
1
+ module Rubygoo
2
+ # all events in the system are converted to these for internal use by our
3
+ # adapter
4
+ class GooEvent
5
+ attr_accessor :event_type, :data
5
6
 
6
- def initialize(event_type, event_data = nil)
7
- @event_type = event_type
8
- @data = event_data
9
- end
7
+ def initialize(event_type, event_data = nil)
8
+ @event_type = event_type
9
+ @data = event_data
10
+ end
10
11
 
12
+ end
11
13
  end
@@ -1,42 +1,44 @@
1
- class Label < Widget
2
- def initialize(text, opts={})
3
- super opts
4
- @text = text
5
- end
1
+ module Rubygoo
2
+ class Label < Widget
3
+ def initialize(text, opts={})
4
+ super opts
5
+ @text = text
6
+ end
6
7
 
7
- def added()
8
- font = theme_property :font
9
- @font_size = theme_property :font_size
10
- @color = theme_property :color
11
- @bg_color = theme_property :bg_color
12
- @focus_color = theme_property :focus_color
13
- @border_color = theme_property :border_color
14
- @font_file = File.join(@app.theme_dir,font)
8
+ def added()
9
+ font = theme_property :font
10
+ @font_size = theme_property :font_size
11
+ @color = theme_property :color
12
+ @bg_color = theme_property :bg_color
13
+ @focus_color = theme_property :focus_color
14
+ @border_color = theme_property :border_color
15
+ @font_file = File.join(@app.theme_dir,font)
15
16
 
16
- set_text @text
17
- end
18
-
19
- def set_text(text)
20
- @text = text
21
- @rendered_text = @app.renderer.render_text @text, @font_file, @font_size, @color
22
- @rect = Rect.new [@x,@y,@rendered_text.width+@x_pad,@rendered_text.height+@y_pad]
23
- end
24
-
25
- def draw(screen)
26
- if @focussed
27
- screen.fill @focus_color, @rect
28
- elsif @bg_color
29
- screen.fill @bg_color, @rect
17
+ set_text @text
30
18
  end
31
19
 
32
- if @border_color
33
- x1 = @rect[0]
34
- y1 = @rect[1]
35
- x2 = @rect[2] + x1
36
- y2 = @rect[3] + y1
37
- screen.draw_box x1, y1, x2, y2, @border_color
20
+ def set_text(text)
21
+ @text = text
22
+ @rendered_text = @app.renderer.render_text @text, @font_file, @font_size, @color
23
+ @rect = Rect.new [@x,@y,@rendered_text.width+@x_pad,@rendered_text.height+@y_pad]
38
24
  end
39
25
 
40
- screen.draw_image @rendered_text, @x, @y
26
+ def draw(screen)
27
+ if @focussed
28
+ screen.fill @focus_color, @rect
29
+ elsif @bg_color
30
+ screen.fill @bg_color, @rect
31
+ end
32
+
33
+ if @border_color
34
+ x1 = @rect[0]
35
+ y1 = @rect[1]
36
+ x2 = @rect[2] + x1
37
+ y2 = @rect[3] + y1
38
+ screen.draw_box x1, y1, x2, y2, @border_color
39
+ end
40
+
41
+ screen.draw_image @rendered_text, @x, @y, @color
42
+ end
41
43
  end
42
44
  end
@@ -0,0 +1,21 @@
1
+ module Rubygoo
2
+ class MouseCursor < Widget
3
+
4
+ def added()
5
+ cursor = theme_property :mouse_cursor
6
+ @cursor_file = File.join(@app.theme_dir,cursor)
7
+ @color = theme_property :color
8
+ # use a 4px box for now
9
+ @size = 4
10
+ end
11
+
12
+ def draw(screen)
13
+ screen.draw_box @x, @y, @x+@size, @y+@size, @color
14
+ end
15
+
16
+ def mouse_motion(event)
17
+ @x = event.data[:x]
18
+ @y = event.data[:y]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,602 @@
1
+ module Rubygoo
2
+ #--
3
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
4
+ # Copyright (C) 2004-2007 John Croisant
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #++
20
+
21
+ #--
22
+ # Table of Contents:
23
+ #
24
+ # class Rect
25
+ # GENERAL:
26
+ # initialize
27
+ # new_from_object
28
+ # to_s
29
+ # to_a, to_ary
30
+ # []
31
+ # ATTRIBUTES:
32
+ # x, y, w, h [<- accessors]
33
+ # width, height, size
34
+ # left, top, right, bottom
35
+ # center, centerx, centery
36
+ # topleft, topright
37
+ # bottomleft, bottomright
38
+ # midleft, midtop, midright, midbottom
39
+ # UTILITY METHODS:
40
+ # clamp, clamp!
41
+ # clip, clip!
42
+ # collide_hash, collide_hash_all
43
+ # collide_array, collide_array_all
44
+ # collide_point?
45
+ # collide_rect?
46
+ # contain?
47
+ # inflate, inflate!
48
+ # move, move!
49
+ # normalize, normalize!
50
+ # union, union!
51
+ # union_all, union_all!
52
+ #
53
+ # class Surface
54
+ # make_rect
55
+ #
56
+ #++
57
+
58
+ # A Rect is a representation of a rectangle, with four core attributes
59
+ # (x offset, y offset, width, and height) and a variety of functions
60
+ # for manipulating and accessing these attributes.
61
+ #
62
+ # Like all coordinates in Rubygame (and its base library, SDL), x and y
63
+ # offsets are measured from the top-left corner of the screen, with greater
64
+ # y offsets being lower. Thus, specifying the x and y offsets of the Rect
65
+ # is equivalent to setting the location of its top-left corner.
66
+ #
67
+ # In Rubygame, Rects are used for collision detection and describing
68
+ # the area of a Surface to operate on.
69
+ class Rect < Array
70
+
71
+ #--
72
+ # GENERAL
73
+ #++
74
+
75
+ # Create a new Rect, attempting to extract its own information from
76
+ # the given arguments. The arguments must fall into one of these cases:
77
+ #
78
+ # - 4 integers +(x, y, w, h)+.
79
+ # - 1 Rect or Array containing 4 integers +([x, y, w, h])+.
80
+ # - 2 Arrays containing 2 integers each +([x,y], [w,h])+.
81
+ # - 1 object with a +rect+ attribute which is a valid Rect object.
82
+ #
83
+ # All rect core attributes (x,y,w,h) must be integers.
84
+ #
85
+ def initialize(*argv)
86
+ case argv.length
87
+ when 1
88
+ if argv[0].kind_of? Array; super(argv[0])
89
+ elsif argv[0].respond_to? :rect; super(argv[0])
90
+ end
91
+ when 2
92
+ super(argv[0].concat(argv[1]))
93
+ when 4
94
+ super(argv)
95
+ end
96
+ return self
97
+ end
98
+
99
+ # Extract or generate a Rect from the given object, if possible, using the
100
+ # following process:
101
+ #
102
+ # 1. If it's a Rect already, return a duplicate Rect.
103
+ # 2. Elsif it's an Array with at least 4 values, make a Rect from it.
104
+ # 3. Elsif it has a +rect+ attribute., perform (1) and (2) on that.
105
+ # 4. Otherwise, raise TypeError.
106
+ #
107
+ # See also Surface#make_rect()
108
+ def Rect.new_from_object(object)
109
+ case(object)
110
+ when Rect
111
+ return object.dup
112
+ when Array
113
+ if object.length >= 4
114
+ return Rect.new(object)
115
+ else
116
+ raise(ArgumentError,"Array does not have enough indices to be made into a Rect (%d for 4)."%object.length )
117
+ end
118
+ else
119
+ begin
120
+ case(object.rect)
121
+ when Rect
122
+ return object.rect.dup
123
+ when Array
124
+ if object.rect.length >= 4
125
+ return Rect.new(object.rect)
126
+ else
127
+ raise(ArgumentError,"Array does not have enough indices to be made into a Rect (%d for 4)."%object.rect.length )
128
+ end
129
+ end # case object.rect
130
+ rescue NoMethodError # if no rect.rect
131
+ raise(TypeError,"Object must be a Rect or Array [x,y,w,h], or have an attribute called 'rect'. (Got %s instance.)"%object.class)
132
+ end
133
+ end # case object
134
+ end
135
+
136
+
137
+ # Print the Rect in the form "+#<Rect [x,y,w,h]>+"
138
+ def to_s; "#<Rect [%s,%s,%s,%s]>"%self; end
139
+
140
+ # Print the Rect in the form "+#<Rect:id [x,y,w,h]>+"
141
+ def inspect; "#<Rect:#{self.object_id} [%s,%s,%s,%s]>"%self; end
142
+
143
+ #--
144
+ # ATTRIBUTES
145
+ #++
146
+
147
+ # Returns self.at(0)
148
+ def x; return self.at(0); end
149
+ # Sets self[0] to +val+
150
+ def x=(val); self[0] = val; end
151
+
152
+ alias left x
153
+ alias left= x=;
154
+ alias l x
155
+ alias l= x=;
156
+
157
+ # Returns self.at(1)
158
+ def y; return self.at(1); end
159
+ # Sets self[1] to +val+
160
+ def y=(val); self[1] = val; end
161
+
162
+ alias top y
163
+ alias top= y=;
164
+ alias t y
165
+ alias t= y=;
166
+
167
+ # Returns self.at(2)
168
+ def w; return self.at(2); end
169
+ # Sets self[2] to +val+
170
+ def w=(val); self[2] = val; end
171
+
172
+ alias width w
173
+ alias width= w=;
174
+
175
+ # Returns self.at(3)
176
+ def h; return self.at(3); end
177
+ # Sets self[3] to +val+
178
+ def h=(val); self[3] = val; end
179
+
180
+ alias height h
181
+ alias height= h=;
182
+
183
+ # Return the width and height of the Rect.
184
+ def size; return self[2,2]; end
185
+
186
+ # Set the width and height of the Rect.
187
+ def size=(size)
188
+ raise ArgumentError, "Rect#size= takes an Array of form [width, height]." if size.size != 2
189
+ self[2,2] = size
190
+ size
191
+ end
192
+
193
+ # Return the x coordinate of the right side of the Rect.
194
+ def right; return self.at(0)+self.at(2); end
195
+
196
+ # Set the x coordinate of the right side of the Rect by translating the
197
+ # Rect (adjusting the x offset).
198
+ def right=(r); self[0] = r - self.at(2); return r; end
199
+
200
+ alias r right
201
+ alias r= right=;
202
+
203
+ # Return the y coordinate of the bottom side of the Rect.
204
+ def bottom; return self.at(1)+self.at(3); end
205
+
206
+ # Set the y coordinate of the bottom side of the Rect by translating the
207
+ # Rect (adjusting the y offset).
208
+ def bottom=(b); self[1] = b - self.at(3); return b; end
209
+
210
+ alias b bottom
211
+ alias b= bottom=;
212
+
213
+ # Return the x and y coordinates of the center of the Rect.
214
+ def center; return self.centerx, self.centery; end
215
+
216
+ # Set the x and y coordinates of the center of the Rect by translating the
217
+ # Rect (adjusting the x and y offsets).
218
+ def center=(center)
219
+ raise ArgumentError, "Rect#center= takes an Array of the form [x,y]." if center.size != 2
220
+ self.centerx, self.centery = center
221
+ center
222
+ end
223
+ alias c center
224
+ alias c= center=;
225
+
226
+ # Return the x coordinate of the center of the Rect
227
+ def centerx; return self.at(0)+(self.at(2).div(2)); end
228
+
229
+ # Set the x coordinate of the center of the Rect by translating the
230
+ # Rect (adjusting the x offset).
231
+ def centerx=(x); self[0] = x - (self.at(2).div(2)); return x; end
232
+
233
+ alias cx centerx
234
+ alias cx= centerx=;
235
+
236
+ # Return the y coordinate of the center of the Rect
237
+ def centery; return self.at(1)+(self.at(3).div(2)); end
238
+
239
+ # Set the y coordinate of the center of the Rect by translating the
240
+ # Rect (adjusting the y offset).
241
+ def centery=(y); self[1] = y- (self.at(3).div(2)); return y; end
242
+
243
+ alias cy centery
244
+ alias cy= centery=;
245
+
246
+ # Return the x and y coordinates of the top-left corner of the Rect
247
+ def topleft; return self[0,2].to_a; end
248
+
249
+ # Set the x and y coordinates of the top-left corner of the Rect by
250
+ # translating the Rect (adjusting the x and y offsets).
251
+ def topleft=(topleft)
252
+ raise ArgumentError, "Rect#topright= takes an Array of form [x, y]." if topleft.size != 2
253
+ self[0,2] = topleft
254
+ return topleft
255
+ end
256
+
257
+ alias tl topleft
258
+ alias tl= topleft=;
259
+
260
+ # Return the x and y coordinates of the top-right corner of the Rect
261
+ def topright; return self.right, self.at(1); end
262
+
263
+ # Set the x and y coordinates of the top-right corner of the Rect by
264
+ # translating the Rect (adjusting the x and y offsets).
265
+ def topright=(topright)
266
+ raise ArgumentError, "Rect#topright= takes an Array of form [x, y]." if topright.size != 2
267
+ self.right, self[1] = topright
268
+ return topright
269
+ end
270
+
271
+ alias tr topright
272
+ alias tr= topright=;
273
+
274
+ # Return the x and y coordinates of the bottom-left corner of the Rect
275
+ def bottomleft; return self.at(0), self.bottom; end
276
+
277
+ # Set the x and y coordinates of the bottom-left corner of the Rect by
278
+ # translating the Rect (adjusting the x and y offsets).
279
+ def bottomleft=(bottomleft)
280
+ raise ArgumentError, "Rect#bottomleft= takes an Array of form [x, y]." if bottomleft.size != 2
281
+ self[0], self.bottom = bottomleft
282
+ return bottomleft
283
+ end
284
+
285
+ alias bl bottomleft
286
+ alias bl= bottomleft=;
287
+
288
+ # Return the x and y coordinates of the bottom-right corner of the Rect
289
+ def bottomright; return self.right, self.bottom; end
290
+
291
+ # Set the x and y coordinates of the bottom-right corner of the Rect by
292
+ # translating the Rect (adjusting the x and y offsets).
293
+ def bottomright=(bottomright)
294
+ raise ArgumentError, "Rect#bottomright= takes an Array of form [x, y]." if bottomright.size != 2
295
+ self.right, self.bottom = bottomright
296
+ return bottomright
297
+ end
298
+
299
+ alias br bottomright
300
+ alias br= bottomright=;
301
+
302
+ # Return the x and y coordinates of the midpoint on the left side of the
303
+ # Rect.
304
+ def midleft; return self.at(0), self.centery; end
305
+
306
+ # Set the x and y coordinates of the midpoint on the left side of the Rect
307
+ # by translating the Rect (adjusting the x and y offsets).
308
+ def midleft=(midleft)
309
+ raise ArgumentError, "Rect#midleft= takes an Array of form [x, y]." if midleft.size != 2
310
+ self[0], self.centery = midleft
311
+ return midleft
312
+ end
313
+
314
+ alias ml midleft
315
+ alias ml= midleft=;
316
+
317
+ # Return the x and y coordinates of the midpoint on the left side of the
318
+ # Rect.
319
+ def midtop; return self.centerx, self.at(1); end
320
+
321
+ # Set the x and y coordinates of the midpoint on the top side of the Rect
322
+ # by translating the Rect (adjusting the x and y offsets).
323
+ def midtop=(midtop)
324
+ raise ArgumentError, "Rect#midtop= takes an Array of form [x, y]." if midtop.size != 2
325
+ self.centerx, self[1] = midtop
326
+ return midtop
327
+ end
328
+
329
+ alias mt midtop
330
+ alias mt= midtop=;
331
+
332
+ # Return the x and y coordinates of the midpoint on the left side of the
333
+ # Rect.
334
+ def midright; return self.right, self.centery; end
335
+
336
+ # Set the x and y coordinates of the midpoint on the right side of the Rect
337
+ # by translating the Rect (adjusting the x and y offsets).
338
+ def midright=(midright)
339
+ raise ArgumentError, "Rect#midright= takes an Array of form [x, y]." if midright.size != 2
340
+ self.right, self.centery = midright
341
+ return midright
342
+ end
343
+
344
+ alias mr midright
345
+ alias mr= midright=;
346
+
347
+ # Return the x and y coordinates of the midpoint on the left side of the
348
+ # Rect.
349
+ def midbottom; return self.centerx, self.bottom; end
350
+
351
+ # Set the x and y coordinates of the midpoint on the bottom side of the
352
+ # Rect by translating the Rect (adjusting the x and y offsets).
353
+ def midbottom=(midbottom)
354
+ raise ArgumentError, "Rect#midbottom= takes an Array of form [x, y]." if midbottom.size != 2
355
+ self.centerx, self.bottom = midbottom
356
+ return midbottom
357
+ end
358
+
359
+ alias mb midbottom
360
+ alias mb= midbottom=;
361
+
362
+ #--
363
+ # UTILITY METHODS
364
+ #++
365
+
366
+
367
+ # As #clamp!, but the original caller is not changed.
368
+ def clamp(rect)
369
+ self.dup.clamp!(rect)
370
+ end
371
+
372
+ # Translate the calling Rect to be entirely inside the given Rect. If
373
+ # the caller is too large along either axis to fit in the given rect,
374
+ # it is centered with respect to the given rect, along that axis.
375
+ def clamp!(rect)
376
+ nself = self.normalize
377
+ rect = Rect.new_from_object(rect)
378
+ #If self is inside given, there is no need to move self
379
+ unless rect.contain?(nself)
380
+
381
+ #If self is too wide:
382
+ if nself.at(2) >= rect.at(2)
383
+ self[0] = rect.centerx - nself.at(2).div(2)
384
+ #Else self is not too wide
385
+ else
386
+ #If self is to the left of arg
387
+ if nself.at(0) < rect.at(0)
388
+ self[0] = rect.at(0)
389
+ #If self is to the right of arg
390
+ elsif nself.right > rect.right
391
+ self[0] = rect.right - nself.at(2)
392
+ #Otherwise, leave x alone
393
+ end
394
+ end
395
+
396
+ #If self is too tall:
397
+ if nself.at(3) >= rect.at(3)
398
+ self[1] = rect.centery - nself.at(3).div(2)
399
+ #Else self is not too tall
400
+ else
401
+ #If self is above arg
402
+ if nself.at(1) < rect.at(1)
403
+ self[1] = rect.at(1)
404
+ #If self below arg
405
+ elsif nself.bottom > rect.bottom
406
+ self[1] = rect.bottom - nself.at(3)
407
+ #Otherwise, leave y alone
408
+ end
409
+ end
410
+ end
411
+ return self
412
+ end
413
+
414
+ # As #clip!, but the original caller is not changed.
415
+ def clip(rect)
416
+ self.dup.clip!(rect)
417
+ end
418
+
419
+ # Crop the calling Rect to be entirely inside the given Rect. If the
420
+ # caller does not intersect the given Rect at all, its width and height
421
+ # are set to zero, but its x and y offsets are not changed.
422
+ #
423
+ # As a side effect, the Rect is normalized.
424
+ def clip!(rect)
425
+ nself = self.normalize
426
+ other = Rect.new_from_object(rect).normalize!
427
+ if self.collide_rect?(other)
428
+ self[0] = [nself.at(0), other.at(0)].max
429
+ self[1] = [nself.at(1), other.at(1)].max
430
+ self[2] = [nself.right, other.right].min - self.at(0)
431
+ self[3] = [nself.bottom, other.bottom].min - self.at(1)
432
+ else #if they do not intersect at all:
433
+ self[0], self[1] = nself.topleft
434
+ self[2], self[3] = 0, 0
435
+ end
436
+ return self
437
+ end
438
+
439
+ # Iterate through all key/value pairs in the given hash table, and
440
+ # return the first pair whose value is a Rect that collides with the
441
+ # caller.
442
+ #
443
+ # Because a hash table is unordered, you should not expect any
444
+ # particular Rect to be returned first.
445
+ def collide_hash(hash_rects)
446
+ hash_rects.each { |key,value|
447
+ if value.collide_rect?+(self); return [key,value]; end
448
+ }
449
+ return nil
450
+ end
451
+
452
+ # Iterate through all key/value pairs in the given hash table, and
453
+ # return an Array of every pair whose value is a Rect that collides
454
+ # the caller.
455
+ #
456
+ # Because a hash table is unordered, you should not expect the returned
457
+ # pairs to be in any particular order.
458
+ def collide_hash_all(hash_rects)
459
+ hash_rects.select { |key,value|
460
+ value.collide_rect?+(self)
461
+ }
462
+ end
463
+
464
+ # Iterate through all elements in the given Array, and return
465
+ # the *index* of the first element which is a Rect that collides with
466
+ # the caller.
467
+ def collide_array(array_rects)
468
+ for i in (0...(array_rects.length))
469
+ if array_rects[i].collide_rect?(self)
470
+ return i
471
+ end
472
+ end
473
+ return nil
474
+ end
475
+
476
+ # Iterate through all elements in the given Array, and return
477
+ # an Array containing the *indices* of every element that is a Rect
478
+ # that collides with the caller.
479
+ def collide_array_all(array_rects)
480
+ indexes = []
481
+ for i in (0...(array_rects.length))
482
+ if array_rects[i].collide_rect?(self)
483
+ indexes += [i]
484
+ end
485
+ end
486
+ return indexes
487
+ end
488
+
489
+ # True if the point is inside (including on the border) of the caller.
490
+ # If you have Array of coordinates, you can use collide_point?(*coords).
491
+ def collide_point?(x,y)
492
+ nself = normalize()
493
+ x.between?(nself.left,nself.right) && y.between?(nself.top,nself.bottom)
494
+ end
495
+
496
+ # True if the caller and the given Rect overlap (or touch) at all.
497
+ def collide_rect?(rect)
498
+ nself = self.normalize
499
+ rect = Rect.new_from_object(rect).normalize!
500
+ return ((nself.l >= rect.l && nself.l <= rect.r) or (rect.l >= nself.l && rect.l <= nself.r)) &&
501
+ ((nself.t >= rect.t && nself.t <= rect.b) or (rect.t >= nself.t && rect.t <= nself.b))
502
+ end
503
+
504
+ # True if the given Rect is totally within the caller. Borders may
505
+ # overlap.
506
+ def contain?(rect)
507
+ nself = self.normalize
508
+ rect = Rect.new_from_object(rect).normalize!
509
+ return (nself.left <= rect.left and rect.right <= nself.right and
510
+ nself.top <= rect.top and rect.bottom <= nself.bottom)
511
+ end
512
+
513
+ # As #inflate!, but the original caller is not changed.
514
+ def inflate(x,y)
515
+ return self.class.new(self.at(0) - x.div(2),
516
+ self.at(1) - y.div(2),
517
+ self.at(2) + x,
518
+ self.at(3) + y)
519
+ end
520
+
521
+ # Increase the Rect's size is the x and y directions, while keeping the
522
+ # same center point. For best results, expand by an even number.
523
+ # X and y inflation can be given as an Array or as separate values.
524
+ def inflate!(x,y)
525
+ self[0] -= x.div(2)
526
+ self[1] -= y.div(2)
527
+ self[2] += x
528
+ self[3] += y
529
+ return self
530
+ end
531
+
532
+ # As #move!, but the original caller is not changed.
533
+ def move(x,y)
534
+ self.dup.move!(x,y)
535
+ end
536
+
537
+ # Translate the Rect by the given amounts in the x and y directions.
538
+ # Positive values are rightward for x and downward for y.
539
+ # X and y movement can be given as an Array or as separate values.
540
+ def move!(x,y)
541
+ self[0]+=x; self[1]+=y
542
+ return self
543
+ end
544
+
545
+ # As #normalize!, but the original caller is not changed.
546
+ def normalize
547
+ self.dup.normalize!()
548
+ end
549
+
550
+ # Fix Rects that have negative width or height, without changing the
551
+ # area it represents. Has no effect on Rects with non-negative width
552
+ # and height. Some Rect methods will automatically normalize the Rect.
553
+ def normalize!
554
+ if self.at(2) < 0
555
+ self[0], self[2] = self.at(0)+self.at(2), -self.at(2)
556
+ end
557
+ if self.at(3) < 0
558
+ self[1], self[3] = self.at(1)+self.at(3), -self.at(3)
559
+ end
560
+ self
561
+ end
562
+
563
+ # As #union!, but the original caller is not changed.
564
+ def union(rect)
565
+ self.dup.union!(rect)
566
+ end
567
+
568
+ # Expand the caller to also cover the given Rect. The Rect is still a
569
+ # rectangle, so it may also cover areas that neither of the original
570
+ # Rects did, for example areas between the two Rects.
571
+ def union!(rect)
572
+ self.normalize!
573
+ rleft, rtop = self.topleft
574
+ rright, rbottom = self.bottomright
575
+ r2 = Rect.new_from_object(rect).normalize!
576
+
577
+ rleft = [rleft, r2.left].min
578
+ rtop = [rtop, r2.top].min
579
+ rright = [rright, r2.right].max
580
+ rbottom = [rbottom, r2.bottom].max
581
+
582
+ self[0,4] = rleft, rtop, rright - rleft, rbottom - rtop
583
+ return self
584
+ end
585
+
586
+ # As #union_all!, but the original caller is not changed.
587
+ def union_all(array_rects)
588
+ self.dup.union_all!(array_rects)
589
+ end
590
+
591
+ # Expand the caller to cover all of the given Rects. See also #union!
592
+ def union_all!(array_rects)
593
+ array_rects.each do |r|
594
+ self.union!(r)
595
+ end
596
+ return self
597
+ end
598
+
599
+
600
+ end # class Rect
601
+
602
+ end