implemented fit and fit_ip
[sdlgit/SDL_perl.git] / lib / SDL / Game / Rect.pm
CommitLineData
389e4b7b 1package SDL::Game::Rect;
2use strict;
3use warnings;
f193ea4b 4use Carp;
0abf088c 5use base 'SDL::Rect';
389e4b7b 6
7our $VERSION = '0.01';
8
9sub new {
10 my $class = shift;
0abf088c 11 my $x = shift || 0;
12 my $y = shift || 0;
13 my $w = shift || 0;
14 my $h = shift || 0;
15
43a05747 16 my $self = $class->SUPER::new($x, $y, $w, $h);
0abf088c 17 unless ($$self) {
f193ea4b 18 #require Carp;
19 croak SDL::GetError();
0abf088c 20 }
21 bless $self, $class;
22 return $self;
389e4b7b 23}
24
25#############################
26## extra accessors
27#############################
28sub bottom {
29 my ($self, $val) = (@_);
30 if (defined $val) {
0abf088c 31 $self->top($val - $self->height); # y = val - height
389e4b7b 32 }
0abf088c 33 return $self->top + $self->height; # y + height
389e4b7b 34}
35
36sub right {
37 my ($self, $val) = (@_);
38 if (defined $val) {
0abf088c 39 $self->left($val - $self->width); # x = val - width
389e4b7b 40 }
0abf088c 41 return $self->left + $self->width; # x + width
389e4b7b 42}
43
44sub centerx {
45 my ($self, $val) = (@_);
46 if (defined $val) {
0abf088c 47 $self->left($val - ($self->width >> 1)); # x = val - (width/2)
389e4b7b 48 }
0abf088c 49 return $self->left + ($self->width >> 1); # x + (width/2)
389e4b7b 50}
51
52sub centery {
53 my ($self, $val) = (@_);
54 if (defined $val) {
0abf088c 55 $self->top($val - ($self->height >> 1)); # y = val - (height/2)
389e4b7b 56 }
0abf088c 57 return $self->top + ($self->height >> 1); # y + (height/2)
389e4b7b 58}
59
60sub size {
61 my ($self, $w, $h) = (@_);
62
0abf088c 63 return ($self->width, $self->height) # (width, height)
389e4b7b 64 unless (defined $w or defined $h);
65
66 if (defined $w) {
0abf088c 67 $self->width($w); # width
389e4b7b 68 }
69 if (defined $h) {
0abf088c 70 $self->height($h); # height
389e4b7b 71 }
72}
73
74sub topleft {
75 my ($self, $y, $x) = (@_);
76
0abf088c 77 return ($self->top, $self->left) # (top, left)
389e4b7b 78 unless (defined $y or defined $x);
79
80 if (defined $x) {
0abf088c 81 $self->left($x); # left
389e4b7b 82 }
83 if (defined $y) {
0abf088c 84 $self->top($y); # top
389e4b7b 85 }
86 return;
87}
88
89sub midleft {
90 my ($self, $centery, $x) = (@_);
91
0abf088c 92 return ($self->top + ($self->height >> 1), $self->left) # (centery, left)
389e4b7b 93 unless (defined $centery or defined $x);
94
95 if (defined $x) {
0abf088c 96 $self->left($x); # left
389e4b7b 97 }
98 if (defined $centery) {
0abf088c 99 $self->top($centery - ($self->height >> 1)); # y = centery - (height/2)
389e4b7b 100 }
101 return;
102}
103
104sub bottomleft {
105 my ($self, $bottom, $x) = (@_);
106
0abf088c 107 return ($self->top + $self->height, $self->left) # (bottom, left)
389e4b7b 108 unless (defined $bottom or defined $x);
109
110 if (defined $x) {
0abf088c 111 $self->left($x); # left
389e4b7b 112 }
113 if (defined $bottom) {
0abf088c 114 $self->top($bottom - $self->height); # y = bottom - height
389e4b7b 115 }
116 return;
117}
118
119sub center {
120 my ($self, $centerx, $centery) = (@_);
121
0abf088c 122 return ($self->left + ($self->width >> 1), $self->top + ($self->height >> 1))
389e4b7b 123 unless (defined $centerx or defined $centery);
124
125 if (defined $centerx) {
0abf088c 126 $self->left($centerx - ($self->width >> 1)); # x = centerx - (width/2)
389e4b7b 127 }
128 if (defined $centery) {
0abf088c 129 $self->top($centery - ($self->height >> 1)); # y = centery - (height/2)
389e4b7b 130 }
131 return;
132}
133
134sub topright {
135 my ($self, $y, $right) = (@_);
136
0abf088c 137 return ($self->top, $self->left + $self->width) # (top, right)
389e4b7b 138 unless (defined $y or defined $right);
139
140 if (defined $right) {
0abf088c 141 $self->left($right - $self->width); # x = right - width
389e4b7b 142 }
143 if (defined $y) {
0abf088c 144 $self->top($y); # top
389e4b7b 145 }
146 return;
147}
148
149sub midright {
150 my ($self, $centery, $right) = (@_);
151
0abf088c 152 return ($self->top + ($self->height >> 1), $self->left + $self->width) # (centery, right)
389e4b7b 153 unless (defined $centery or defined $right);
154
155 if (defined $right) {
0abf088c 156 $self->left($right - $self->width); # x = right - width
389e4b7b 157 }
158 if (defined $centery) {
0abf088c 159 $self->top($centery - ($self->height >> 1)); # y = centery - (height/2)
389e4b7b 160 }
161 return;
162}
163
164sub bottomright {
165 my ($self, $bottom, $right) = (@_);
166
0abf088c 167 return ($self->top + $self->height, $self->left + $self->width) # (bottom, right)
389e4b7b 168 unless (defined $bottom or defined $right);
169
170 if (defined $right) {
0abf088c 171 $self->left($right - $self->width); # x = right - width
389e4b7b 172 }
173 if (defined $bottom) {
0abf088c 174 $self->top($bottom - $self->height); # y = bottom - height
389e4b7b 175 }
176 return;
177}
178
179sub midtop {
180 my ($self, $centerx, $y) = (@_);
181
0abf088c 182 return ($self->left + ($self->width >> 1), $self->top) # (centerx, top)
389e4b7b 183 unless (defined $centerx or defined $y);
184
185 if (defined $y) {
0abf088c 186 $self->top($y); # top
389e4b7b 187 }
188 if (defined $centerx) {
0abf088c 189 $self->left($centerx - ($self->width >> 1)); # x = centerx - (width/2)
389e4b7b 190 }
191 return;
192}
193
194sub midbottom {
195 my ($self, $centerx, $bottom) = (@_);
196
0abf088c 197 return ($self->left + ($self->width >> 1), $self->top + $self->height) # (centerx, bottom)
389e4b7b 198 unless (defined $centerx or defined $bottom);
199
200 if (defined $bottom) {
0abf088c 201 $self->top($bottom - $self->height); # y = bottom - height
389e4b7b 202 }
203 if (defined $centerx) {
0abf088c 204 $self->left($centerx - ($self->width >> 1)); # x = centerx - (width/2)
389e4b7b 205 }
206 return;
207}
208
5674d738 209###############################
210## methods ##
211###############################
212
213sub duplicate {
214}
215
216sub copy {
217 my $self = shift;
218 return $self->new(
219 -top => $self->top,
220 -left => $self->left,
221 -width => $self->width,
222 -height => $self->height,
223 );
224}
225
226sub move {
227 my ($self, $x, $y) = (@_);
228 if (not defined $x or not defined $y) {
f193ea4b 229 #require Carp;
230 croak "must receive x and y positions as argument";
5674d738 231 }
232 return $self->new(
233 -top => $self->top + $y,
234 -left => $self->left + $x,
235 -width => $self->width,
236 -height => $self->height,
237 );
238}
239
240sub move_ip {
241 my ($self, $x, $y) = (@_);
242 if (not defined $x or not defined $y) {
f193ea4b 243 #require Carp;
244 croak "must receive x and y positions as argument";
5674d738 245 }
246 $self->x($self->x + $x);
247 $self->y($self->y + $y);
248
249 return;
250}
251
252sub inflate {
253 my ($self, $x, $y) = (@_);
254 if (not defined $x or not defined $y) {
f193ea4b 255 #require Carp;
256 croak "must receive x and y positions as argument";
5674d738 257 }
258
259 return $self->new(
260 -left => $self->left - ($x / 2),
261 -top => $self->top - ($y / 2),
262 -width => $self->width + $x,
263 -height => $self->height + $y,
264 );
265}
266
267sub inflate_ip {
268 my ($self, $x, $y) = (@_);
269 if (not defined $x or not defined $y) {
f193ea4b 270 #require Carp;
271 croak "must receive x and y positions as argument";
5674d738 272 }
273
274 $self->x( $self->x - ($x / 2) );
275 $self->y( $self->y - ($y / 2) );
276
277 $self->w( $self->w + $x );
278 $self->h( $self->h + $y );
279}
280
57f262e8 281sub _get_clamp_coordinates {
282 my ($self_pos, $self_len, $rect_pos, $rect_len) = (@_);
283
284 if ($self_len >= $rect_len) {
285 return $rect_pos + ($rect_len / 2) - ($self_len / 2);
286 }
287 elsif ($self_pos < $rect_pos) {
288 return $rect_pos;
289 }
290 elsif ( ($self_pos + $self_len) > ($rect_pos + $rect_len) ) {
291 return $rect_pos + $rect_len - $self_len;
292 }
293 else {
294 return $self_pos;
295 }
296}
297
298sub clamp {
299 my ($self, $rect) = (@_);
300
301 unless ($rect->isa('SDL::Rect')) {
302 croak "must receive an SDL::Rect-based object";
303 }
304
305 my $x = _get_clamp_coordinates($self->x, $self->w, $rect->x, $rect->w);
306 my $y = _get_clamp_coordinates($self->y, $self->h, $rect->y, $rect->h);
307
308 return $self->new($x, $y, $self->w, $self->h);
309}
310
311sub clamp_ip {
312 my ($self, $rect) = (@_);
313
314 unless ($rect->isa('SDL::Rect')) {
315 croak "must receive an SDL::Rect-based object";
316 }
317
318 my $x = _get_clamp_coordinates($self->x, $self->w, $rect->x, $rect->w);
319 my $y = _get_clamp_coordinates($self->y, $self->h, $rect->y, $rect->h);
320
321 $self->x($x);
322 $self->y($y);
323
324 return;
325}
389e4b7b 326
74f8c259 327sub _get_intersection_coordinates {
328 my ($self, $rect) = (@_);
329 my ($x, $y, $w, $h);
330
331INTERSECTION:
332 {
333 ### Left
334 if (($self->x >= $rect->x) && ($self->x < ($rect->x + $rect->w))) {
335 $x = $self->x;
336 }
337 elsif (($rect->x >= $self->x) && ($rect->x < ($self->x + $self->w))) {
338 $x = $rect->x;
339 }
340 else {
341 last INTERSECTION;
342 }
343
344 ## Right
345 if ((($self->x + $self->w) > $rect->x) && (($self->x + $self->w) <= ($rect->x + $rect->w))) {
346 $w = ($self->x + $self->w) - $x;
347 }
348 elsif ((($rect->x + $rect->w) > $self->x) && (($rect->x + $rect->w) <= ($self->x + $self->w))) {
349 $w = ($rect->x + $rect->w) - $x;
350 }
351 else {
352 last INTERSECTION;
353 }
354
355 ## Top
356 if (($self->y >= $rect->y) && ($self->y < ($rect->y + $rect->h))) {
357 $y = $self->y;
358 }
359 elsif (($rect->y >= $self->y) && ($rect->y < ($self->y + $self->h))) {
360 $y = $rect->y;
361 }
362 else {
363 last INTERSECTION;
364 }
365
366 ## Bottom
367 if ((($self->y + $self->h) > $rect->y) && (($self->y + $self->h) <= ($rect->y + $rect->h))) {
368 $h = ($self->y + $self->h) - $y;
369 }
370 elsif ((($rect->y + $rect->h) > $self->y) && (($rect->y + $rect->h) <= ($self->y + $self->h))) {
371 $h = ($rect->y + $rect->h) - $y;
372 }
373 else {
374 last INTERSECTION;
375 }
376
377 return ($x, $y, $w, $h);
378 }
379
380 # if we got here, the two rects do not intersect
381 return ($self->x, $self->y, 0, 0);
382
383}
384
385sub clip {
386 my ($self, $rect) = (@_);
387
388 unless ($rect->isa('SDL::Rect')) {
389 croak "must receive an SDL::Rect-based object";
390 }
391
392 my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect);
393
394 return $self->new($x, $y, $w, $h);
395}
396
397sub clip_ip {
398 my ($self, $rect) = (@_);
399
400 unless ($rect->isa('SDL::Rect')) {
401 croak "must receive an SDL::Rect-based object";
402 }
403
404 my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect);
405
406 $self->x($x);
407 $self->y($y);
408 $self->w($w);
409 $self->h($h);
410
411 return;
412}
413
26622c70 414
415sub _test_union {
416 my ($self, $rect) = (@_);
417 my ($x, $y, $w, $h);
418
419 $x = $self->x < $rect->x ? $self->x : $rect->x; # MIN
420 $y = $self->y < $rect->y ? $self->y : $rect->y; # MIN
421
422 $w = ($self->x + $self->w) > ($rect->x + $rect->w)
423 ? ($self->x + $self->w) - $x
424 : ($rect->x + $rect->w) - $x
425 ; # MAX
426
427 $h = ($self->y + $self->h) > ($rect->y + $rect->h)
428 ? ($self->y + $self->h) - $y
429 : ($rect->y + $rect->h) - $y
430 ; # MAX
431
432 return ($x, $y, $w, $h);
433}
434
435sub union {
436 my ($self, $rect) = (@_);
437
438 unless ($rect->isa('SDL::Rect')) {
439 croak "must receive an SDL::Rect-based object";
440 }
441
442 my ($x, $y, $w, $h) = _test_union($self, $rect);
443 return $self->new($x, $y, $w, $h);
444}
445
446sub union_ip {
447 my ($self, $rect) = (@_);
448
449 unless ($rect->isa('SDL::Rect')) {
450 croak "must receive an SDL::Rect-based object";
451 }
452
453 my ($x, $y, $w, $h) = _test_union($self, $rect);
454
455 $self->x($x);
456 $self->y($y);
457 $self->w($w);
458 $self->y($h);
459
460 return;
461}
462
71854fd9 463sub _test_unionall {
464 my ($self, $rects) = (@_);
465
466 # initial values for union rect
467 my $left = $self->x;
468 my $top = $self->y;
469 my $right = $self->x + $self->w;
470 my $bottom = $self->y + $self->h;
471
472 foreach my $rect (@{$rects}) {
473 unless ($rect->isa('SDL::Rect')) {
474 # TODO: better error message, maybe saying which item
475 # is the bad one (by list position)
476 croak "must receive an array reference of SDL::Rect-based objects";
477 }
478
479 $left = $rect->x if $rect->x < $left; # MIN
480 $top = $rect->y if $rect->y < $top; # MIN
481 $right = ($rect->x + $rect->w) if ($rect->x + $rect->w) > $right; # MAX
482 $bottom = ($rect->y + $rect->h) if ($rect->y + $rect->h) > $bottom; # MAX
483 }
484
485 return ($left, $top, $right - $left, $bottom - $top);
486}
487
488sub unionall {
489 my ($self, $rects) = (@_);
490
491 croak "must receive an array reference of SDL::Rect-based objects"
492 unless defined $rects and ref $rects eq 'ARRAY';
493
494 my ($x, $y, $w, $h) = _test_unionall($self, $rects);
495
496 return $self->new($x, $y, $w, $h);
497}
498
499sub unionall_ip {
500 my ($self, $rects) = (@_);
501
502 croak "must receive an array reference of SDL::Rect-based objects"
503 unless defined $rects and ref $rects eq 'ARRAY';
504
505 my ($x, $y, $w, $h) = _test_unionall($self, $rects);
506
507 $self->x($x);
508 $self->y($y);
509 $self->w($w);
510 $self->h($h);
511
512 return;
513}
514
64c66a05 515sub _check_fit {
516 my ($self, $rect) = (@_);
517
518 my $x_ratio = $self->w / $rect->w;
519 my $y_ratio = $self->h / $rect->h;
520 my $max_ratio = ($x_ratio > $y_ratio) ? $x_ratio : $y_ratio;
521
522 my $w = int ($self->w / $max_ratio);
523 my $h = int ($self->h / $max_ratio);
524
525 my $x = $rect->x + int (($rect->w - $w) / 2);
526 my $y = $rect->y + int (($rect->h - $h) / 2);
527
528 return ($x, $y, $w, $h);
529}
530
531sub fit {
532 my ($self, $rect) = (@_);
533
534 unless ($rect->isa('SDL::Rect')) {
535 croak "must receive an SDL::Rect-based object";
536 }
537
538 my ($x, $y, $w, $h) = _check_fit($self, $rect);
539
540 return $self->new ($x, $y, $w, $h);
541}
542
543sub fit_ip {
544 my ($self, $rect) = (@_);
545
546 unless ($rect->isa('SDL::Rect')) {
547 croak "must receive an SDL::Rect-based object";
548 }
549
550 my ($x, $y, $w, $h) = _check_fit($self, $rect);
551
552 $self->x($x);
553 $self->y($y);
554 $self->w($w);
555 $self->h($h);
556
557 return;
558}
559
71854fd9 560
389e4b7b 56142;
562__END__
563
564=head1 NAME
565
566SDL::Game::Rect - SDL::Game object for storing and manipulating rectangular coordinates
567
568=head1 SYNOPSIS
569
570
571=head1 DESCRIPTION
572
573C<< SDL::Game::Rect >> object are used to store and manipulate rectangular areas. Rect objects are created from a combination of left (or x), top (or y), width (or w) and height (or h) values, just like raw C<< SDL::Rect objects >>.
574
575All C<< SDL::Game::Rect >> methods that change either position or size of a Rect return B<a new copy> of the Rect with the affected changes. The original Rect is B<not> modified. If you wish to modify the current Rect object, you can use the equivalent "in-place" methods that do not return but instead affects the original Rect. These "in-place" methods are denoted with the "ip" suffix. Note that changing a Rect's attribute is I<always> an in-place operation.
576
577
578=head2 ATTRIBUTES
579
580All Rect attributes are acessors, meaning you can get them by name, and set them by passing a value:
581
582 $rect->left(15);
583 $rect->left; # 15
584
585The Rect object has several attributes which can be used to resize, move and align the Rect.
586
587
588=over 4
589
590=item * width, w - gets/sets object's width
591
592=item * height, h - gets/sets object's height
593
594=item * left, x - moves the object left position to match the given coordinate
595
596=item * top, y - moves the object top position to match the given coordinate
597
598=item * bottom - moves the object bottom position to match the given coordinate
599
600=item * right - moves the object right position to match the given coordinate
601
602=item * centerx - moves the object's horizontal center to match the given coordinate
603
604=item * centery - moves the object's vertical center to match the given coordinate
605
606=back
607
608Some of the attributes above can be fetched or set in pairs:
609
610 $rect->topleft(10, 15); # top is now 10, left is now 15
611
612 my ($width, $height) = $rect->size;
613
614
615=over 4
616
617=item * size - gets/sets object's size (width, height)
618
619=item * topleft - gets/sets object's top and left positions
620
621=item * midleft - gets/sets object's vertical center and left positions
622
623=item * bottomleft - gets/sets object's bottom and left positions
624
625=item * center - gets/sets object's center (horizontal(x), vertical(y))
626
627=item * topright - gets/sets object's top and right positions
628
629=item * midright - gets/sets object's vertical center and right positions
630
631=item * bottomright - gets/sets object's bottom and right positions
632
633=item * midtop - gets/sets object's horizontal center and top positions
634
635=item * midbottom - gets/sets object's horizontal center and bottom positions
636
637=back
638
639
640=head2 METHODS
641
642Methods denoted as receiving Rect objects can receive either C<<SDL::Game::Rect>> or raw C<<SDL::Rect>> objects.
643
644=head3 new ($left, $top, $width, $height)
645
646Returns a new Rect object with the given coordinates. If any value is omitted (by passing undef), 0 is used instead.
647
648=head3 copy
649
650=head3 duplicate
651
652Returns a new Rect object having the same position and size as the original
653
654=head3 move(x, y)
655
656Returns a new Rect that is moved by the given offset. The x and y arguments can be any integer value, positive or negative.
657
658=head3 move_ip(x, y)
659
660Same as C<<move>> above, but moves the current Rect in place and returns nothing.
661
662=head3 inflate(x, y)
663
664Grows or shrinks the rectangle. Returns a new Rect with the size changed by the given offset. The rectangle remains centered around its current center. Negative values will return a shrinked rectangle instead.
665
666=head3 inflate_ip(x, y)
667
668Same as C<<inflate>> above, but grows/shrinks the current Rect in place and returns nothing.
669
670=head3 clamp($rect)
671
672Returns a new Rect moved to be completely inside the Rect object passed as an argument. If the current Rect is too large to fit inside the passed Rect, it is centered inside it, but its size is not changed.
673
674=head3 clamp_ip($rect)
675
676Same as C<<clamp>> above, but moves the current Rect in place and returns nothing.
677
678=head3 clip($rect)
679
74f8c259 680Returns a new Rect with the intersection between the two Rect objects, that is, returns a new Rect cropped to be completely inside the Rect object passed as an argument. If the two rectangles do not overlap to begin with, a Rect with 0 size is returned, in the original Rect's (x,y) coordinates.
389e4b7b 681
682=head3 clip_ip($rect)
683
74f8c259 684Same as C<<clip>> above, but crops the current Rect in place and returns nothing. As the original method, the Rect becomes zero-sized if the two rectangles do not overlap to begin with, retaining its (x, y) coordinates.
389e4b7b 685
686=head3 union($rect)
687
688Returns a new rectangle that completely covers the area of the current Rect and the one passed as an argument. There may be area inside the new Rect that is not covered by the originals.
689
690=head3 union_ip($rect)
691
692Same as C<<union>> above, but resizes the current Rect in place and returns nothing.
693
694=head3 unionall( [$rect1, $rect2, ...] )
695
696Returns the union of one rectangle with a sequence of many rectangles, passed as an ARRAY REF.
697
698=head3 unionall_ip( [$rect1, $rect2, ...] )
699
700Same as C<<unionall>> above, but resizes the current Rect in place and returns nothing.
701
702=head3 fit($rect)
703
704Returns a new Rect moved and resized to fit the Rect object passed as an argument. The aspect ratio of the original Rect is preserved, so the new rectangle may be smaller than the target in either width or height.
705
706=head3 fit_ip($rect)
707
708Same as C<<fit>> above, but moves/resizes the current Rect in place and returns nothing.
709
710=head3 normalize
711
712Corrects negative sizes, flipping width/height of the Rect if they have a negative size. No repositioning is made so the rectangle will remain in the same place, but the negative sides will be swapped. This method returns nothing.
713
714=head3 contains($rect)
715
716Returns true (non-zero) when the argument is completely inside the Rect. Otherwise returns undef.
717
718=head3 collidepoint(x, y)
719
720Returns true (non-zero) if the given point is inside the Rect, otherwise returns undef. A point along the right or bottom edge is not considered to be inside the rectangle.
721
722=head3 colliderect($rect)
723
724Returns true (non-zero) if any portion of either rectangles overlap (except for the top+bottom or left+right edges).
725
726=head3 collidelist( [$rect1, $rect2, ...] )
727
728Test whether the rectangle collides with any in a sequence of rectangles, passed as an ARRAY REF. The index of the first collision found is returned. Returns undef if no collisions are found.
729
730=head3 collidelistall( [$rect1, $rect2, ...] )
731
732Returns an ARRAY REF of all the indices that contain rectangles that collide with the Rect. If no intersecting rectangles are found, an empty list ref is returned.
733
734=head3 collidehash( {key1 => $rect1, key2 => $rect2, ...} )
735
736Receives a HASH REF and returns the a (key, value) list with the key and value of the first hash item that collides with the Rect. If no collisions are found, returns (undef, undef).
737
738=head3 collidehashall( {key1 => $rect1, key2 => $rect2, ...} )
739
740Returns a HASH REF of all the key and value pairs that intersect with the Rect. If no collisions are found an empty hash ref is returned.
741
742
743=head1 AUTHOR
744
745Breno G. de Oliveira, C<< <garu at cpan.org> >>
746
747=head1 BUGS
748
749Please report any bugs or feature requests to the bug tracker. I will be notified, and then you'll automatically be notified of progress on your bug as we make changes.
750
751
752=head1 SUPPORT
753
754You can find documentation for this module with the perldoc command.
755
756 perldoc SDL::Game::Rect
757
758
759=head1 ACKNOWLEDGEMENTS
760
761Many thanks to all SDL_Perl contributors, and to the authors of pygame.rect, in which this particular module is heavily based.
762
763=head1 COPYRIGHT & LICENSE
764
765Copyright 2009 Breno G. de Oliveira, all rights reserved.
766
767This program is free software; you can redistribute it and/or modify it
768under the same terms as Perl itself.
769
770
771=head1 SEE ALSO
772
773perl, L<SDL>, L<SDL::Rect>, L<SDL::Game>