remove unnecessary Carp
[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
50644543 213{
214 no strict 'refs';
215 *{'duplicate'} = *{copy};
5674d738 216}
217
218sub copy {
219 my $self = shift;
220 return $self->new(
221 -top => $self->top,
222 -left => $self->left,
223 -width => $self->width,
224 -height => $self->height,
225 );
226}
227
228sub move {
229 my ($self, $x, $y) = (@_);
230 if (not defined $x or not defined $y) {
f193ea4b 231 #require Carp;
232 croak "must receive x and y positions as argument";
5674d738 233 }
234 return $self->new(
235 -top => $self->top + $y,
236 -left => $self->left + $x,
237 -width => $self->width,
238 -height => $self->height,
239 );
240}
241
242sub move_ip {
243 my ($self, $x, $y) = (@_);
244 if (not defined $x or not defined $y) {
f193ea4b 245 #require Carp;
246 croak "must receive x and y positions as argument";
5674d738 247 }
248 $self->x($self->x + $x);
249 $self->y($self->y + $y);
250
251 return;
252}
253
254sub inflate {
255 my ($self, $x, $y) = (@_);
256 if (not defined $x or not defined $y) {
f193ea4b 257 #require Carp;
258 croak "must receive x and y positions as argument";
5674d738 259 }
260
261 return $self->new(
262 -left => $self->left - ($x / 2),
263 -top => $self->top - ($y / 2),
264 -width => $self->width + $x,
265 -height => $self->height + $y,
266 );
267}
268
269sub inflate_ip {
270 my ($self, $x, $y) = (@_);
271 if (not defined $x or not defined $y) {
f193ea4b 272 #require Carp;
273 croak "must receive x and y positions as argument";
5674d738 274 }
275
276 $self->x( $self->x - ($x / 2) );
277 $self->y( $self->y - ($y / 2) );
278
279 $self->w( $self->w + $x );
280 $self->h( $self->h + $y );
281}
282
57f262e8 283sub _get_clamp_coordinates {
284 my ($self_pos, $self_len, $rect_pos, $rect_len) = (@_);
285
286 if ($self_len >= $rect_len) {
287 return $rect_pos + ($rect_len / 2) - ($self_len / 2);
288 }
289 elsif ($self_pos < $rect_pos) {
290 return $rect_pos;
291 }
292 elsif ( ($self_pos + $self_len) > ($rect_pos + $rect_len) ) {
293 return $rect_pos + $rect_len - $self_len;
294 }
295 else {
296 return $self_pos;
297 }
298}
299
300sub clamp {
301 my ($self, $rect) = (@_);
302
303 unless ($rect->isa('SDL::Rect')) {
304 croak "must receive an SDL::Rect-based object";
305 }
306
307 my $x = _get_clamp_coordinates($self->x, $self->w, $rect->x, $rect->w);
308 my $y = _get_clamp_coordinates($self->y, $self->h, $rect->y, $rect->h);
309
310 return $self->new($x, $y, $self->w, $self->h);
311}
312
313sub clamp_ip {
314 my ($self, $rect) = (@_);
315
316 unless ($rect->isa('SDL::Rect')) {
317 croak "must receive an SDL::Rect-based object";
318 }
319
320 my $x = _get_clamp_coordinates($self->x, $self->w, $rect->x, $rect->w);
321 my $y = _get_clamp_coordinates($self->y, $self->h, $rect->y, $rect->h);
322
323 $self->x($x);
324 $self->y($y);
325
326 return;
327}
389e4b7b 328
74f8c259 329sub _get_intersection_coordinates {
330 my ($self, $rect) = (@_);
331 my ($x, $y, $w, $h);
332
333INTERSECTION:
334 {
335 ### Left
336 if (($self->x >= $rect->x) && ($self->x < ($rect->x + $rect->w))) {
337 $x = $self->x;
338 }
339 elsif (($rect->x >= $self->x) && ($rect->x < ($self->x + $self->w))) {
340 $x = $rect->x;
341 }
342 else {
343 last INTERSECTION;
344 }
345
346 ## Right
347 if ((($self->x + $self->w) > $rect->x) && (($self->x + $self->w) <= ($rect->x + $rect->w))) {
348 $w = ($self->x + $self->w) - $x;
349 }
350 elsif ((($rect->x + $rect->w) > $self->x) && (($rect->x + $rect->w) <= ($self->x + $self->w))) {
351 $w = ($rect->x + $rect->w) - $x;
352 }
353 else {
354 last INTERSECTION;
355 }
356
357 ## Top
358 if (($self->y >= $rect->y) && ($self->y < ($rect->y + $rect->h))) {
359 $y = $self->y;
360 }
361 elsif (($rect->y >= $self->y) && ($rect->y < ($self->y + $self->h))) {
362 $y = $rect->y;
363 }
364 else {
365 last INTERSECTION;
366 }
367
368 ## Bottom
369 if ((($self->y + $self->h) > $rect->y) && (($self->y + $self->h) <= ($rect->y + $rect->h))) {
370 $h = ($self->y + $self->h) - $y;
371 }
372 elsif ((($rect->y + $rect->h) > $self->y) && (($rect->y + $rect->h) <= ($self->y + $self->h))) {
373 $h = ($rect->y + $rect->h) - $y;
374 }
375 else {
376 last INTERSECTION;
377 }
378
379 return ($x, $y, $w, $h);
380 }
381
382 # if we got here, the two rects do not intersect
383 return ($self->x, $self->y, 0, 0);
384
385}
386
387sub clip {
388 my ($self, $rect) = (@_);
389
390 unless ($rect->isa('SDL::Rect')) {
391 croak "must receive an SDL::Rect-based object";
392 }
393
394 my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect);
395
396 return $self->new($x, $y, $w, $h);
397}
398
399sub clip_ip {
400 my ($self, $rect) = (@_);
401
402 unless ($rect->isa('SDL::Rect')) {
403 croak "must receive an SDL::Rect-based object";
404 }
405
406 my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect);
407
408 $self->x($x);
409 $self->y($y);
410 $self->w($w);
411 $self->h($h);
412
413 return;
414}
415
26622c70 416
417sub _test_union {
418 my ($self, $rect) = (@_);
419 my ($x, $y, $w, $h);
420
421 $x = $self->x < $rect->x ? $self->x : $rect->x; # MIN
422 $y = $self->y < $rect->y ? $self->y : $rect->y; # MIN
423
424 $w = ($self->x + $self->w) > ($rect->x + $rect->w)
425 ? ($self->x + $self->w) - $x
426 : ($rect->x + $rect->w) - $x
427 ; # MAX
428
429 $h = ($self->y + $self->h) > ($rect->y + $rect->h)
430 ? ($self->y + $self->h) - $y
431 : ($rect->y + $rect->h) - $y
432 ; # MAX
433
434 return ($x, $y, $w, $h);
435}
436
437sub union {
438 my ($self, $rect) = (@_);
439
440 unless ($rect->isa('SDL::Rect')) {
441 croak "must receive an SDL::Rect-based object";
442 }
443
444 my ($x, $y, $w, $h) = _test_union($self, $rect);
445 return $self->new($x, $y, $w, $h);
446}
447
448sub union_ip {
449 my ($self, $rect) = (@_);
450
451 unless ($rect->isa('SDL::Rect')) {
452 croak "must receive an SDL::Rect-based object";
453 }
454
455 my ($x, $y, $w, $h) = _test_union($self, $rect);
456
457 $self->x($x);
458 $self->y($y);
459 $self->w($w);
460 $self->y($h);
461
462 return;
463}
464
71854fd9 465sub _test_unionall {
466 my ($self, $rects) = (@_);
467
468 # initial values for union rect
469 my $left = $self->x;
470 my $top = $self->y;
471 my $right = $self->x + $self->w;
472 my $bottom = $self->y + $self->h;
473
474 foreach my $rect (@{$rects}) {
475 unless ($rect->isa('SDL::Rect')) {
476 # TODO: better error message, maybe saying which item
477 # is the bad one (by list position)
478 croak "must receive an array reference of SDL::Rect-based objects";
479 }
480
481 $left = $rect->x if $rect->x < $left; # MIN
482 $top = $rect->y if $rect->y < $top; # MIN
483 $right = ($rect->x + $rect->w) if ($rect->x + $rect->w) > $right; # MAX
484 $bottom = ($rect->y + $rect->h) if ($rect->y + $rect->h) > $bottom; # MAX
485 }
486
487 return ($left, $top, $right - $left, $bottom - $top);
488}
489
490sub unionall {
491 my ($self, $rects) = (@_);
492
85eb4c83 493 unless (defined $rects and ref $rects eq 'ARRAY') {
494 croak "must receive an array reference of SDL::Rect-based objects";
495 }
71854fd9 496
497 my ($x, $y, $w, $h) = _test_unionall($self, $rects);
498
499 return $self->new($x, $y, $w, $h);
500}
501
502sub unionall_ip {
503 my ($self, $rects) = (@_);
504
85eb4c83 505 unless (defined $rects and ref $rects eq 'ARRAY') {
506 croak "must receive an array reference of SDL::Rect-based objects";
507 }
71854fd9 508
509 my ($x, $y, $w, $h) = _test_unionall($self, $rects);
510
511 $self->x($x);
512 $self->y($y);
513 $self->w($w);
514 $self->h($h);
515
516 return;
517}
518
64c66a05 519sub _check_fit {
520 my ($self, $rect) = (@_);
521
522 my $x_ratio = $self->w / $rect->w;
523 my $y_ratio = $self->h / $rect->h;
524 my $max_ratio = ($x_ratio > $y_ratio) ? $x_ratio : $y_ratio;
525
526 my $w = int ($self->w / $max_ratio);
527 my $h = int ($self->h / $max_ratio);
528
529 my $x = $rect->x + int (($rect->w - $w) / 2);
530 my $y = $rect->y + int (($rect->h - $h) / 2);
531
532 return ($x, $y, $w, $h);
533}
534
535sub fit {
536 my ($self, $rect) = (@_);
537
538 unless ($rect->isa('SDL::Rect')) {
539 croak "must receive an SDL::Rect-based object";
540 }
541
542 my ($x, $y, $w, $h) = _check_fit($self, $rect);
543
544 return $self->new ($x, $y, $w, $h);
545}
546
547sub fit_ip {
548 my ($self, $rect) = (@_);
549
550 unless ($rect->isa('SDL::Rect')) {
551 croak "must receive an SDL::Rect-based object";
552 }
553
554 my ($x, $y, $w, $h) = _check_fit($self, $rect);
555
556 $self->x($x);
557 $self->y($y);
558 $self->w($w);
559 $self->h($h);
560
561 return;
562}
563
f1b79066 564sub normalize {
565 my $self = shift;
566
567 if ($self->w < 0) {
568 $self->x($self->x + $self->w);
569 $self->w(-$self->w);
570 }
571
572 if ($self->h < 0) {
573 $self->y( $self->y + $self->h);
574 $self->h(-$self->h);
575 }
576 return;
577}
578
b6eea8bc 579sub contains {
580 my ($self, $rect) = (@_);
581
582 unless ($rect->isa('SDL::Rect')) {
583 croak "must receive an SDL::Rect-based object";
584 }
585
586 my $contained = ($self->x <= $rect->x)
587 && ($self->y <= $rect->y)
588 && ($self->x + $self->w >= $rect->x + $rect->w)
589 && ($self->y + $self->h >= $rect->y + $rect->h)
590 && ($self->x + $self->w > $rect->x)
591 && ($self->y + $self->h > $rect->y)
592 ;
593
594 return $contained;
595}
71854fd9 596
0064136d 597sub collidepoint {
598 my ($self, $x, $y) = (@_);
599
600 unless (defined $x and defined $y) {
601 croak "must receive (x,y) as arguments";
602 }
603
604 my $inside = $x >= $self->x
605 && $x < $self->x + $self->w
606 && $y >= $self->y
607 && $y < $self->y + $self->h
608 ;
609
610 return $inside;
611}
612
50d0e9ac 613sub _do_rects_intersect {
614 my ($rect_A, $rect_B) = (@_);
615
616 return (
617 ($rect_A->x >= $rect_B->x && $rect_A->x < $rect_B->x + $rect_B->w)
618 || ($rect_B->x >= $rect_A->x && $rect_B->x < $rect_A->x + $rect_A->w)
619 )
620 &&
621 (
622 ($rect_A->y >= $rect_B->y && $rect_A->y < $rect_B->y + $rect_B->h)
623 || ($rect_B->y >= $rect_A->y && $rect_B->y < $rect_A->y + $rect_A->h)
624 )
625 ;
626}
627
628
629sub colliderect {
630 my ($self, $rect) = (@_);
631
632 unless ($rect->isa('SDL::Rect')) {
633 croak "must receive an SDL::Rect-based object";
634 }
635
636 return _do_rects_intersect($self, $rect);
637}
638
85eb4c83 639sub collidelist {
640 my ($self, $rects) = (@_);
641
642 unless (defined $rects and ref $rects eq 'ARRAY') {
643 croak "must receive an array reference of SDL::Rect-based objects";
644 }
645
646 for(my $i = 0; $i < @{$rects}; $i++) {
647 if ( _do_rects_intersect($self, $rects->[$i]) ) {
648 return $i;
649 }
650 }
651 return;
652}
653
dfbe9a27 654sub collidelistall {
655 my ($self, $rects) = (@_);
656
657 unless (defined $rects and ref $rects eq 'ARRAY') {
658 croak "must receive an array reference of SDL::Rect-based objects";
659 }
660
661 my @collisions = ();
662 for(my $i = 0; $i < @{$rects}; $i++) {
663 if ( _do_rects_intersect($self, $rects->[$i]) ) {
664 push @collisions, $i;
665 }
666 }
667 return \@collisions;
668}
85eb4c83 669
ebfa743c 670sub collidehash {
671 my ($self, $rects) = (@_);
672
673 unless (defined $rects and ref $rects eq 'HASH') {
674 croak "must receive an hash reference of SDL::Rect-based objects";
675 }
676
677 while ( my ($key, $value) = each %{$rects} ) {
678 unless ($value->isa('SDL::Rect')) {
679 croak "hash element of key '$key' is not an SDL::Rect-based object";
680 }
681
682 if ( _do_rects_intersect($self, $value) ) {
683 return ($key, $value);
684 }
685 }
686 return (undef, undef);
687}
50d0e9ac 688
ec346238 689sub collidehashall {
690 my ($self, $rects) = (@_);
691
692 unless (defined $rects and ref $rects eq 'HASH') {
693 croak "must receive an hash reference of SDL::Rect-based objects";
694 }
695
696 my %collisions = ();
697 while ( my ($key, $value) = each %{$rects} ) {
698 unless ($value->isa('SDL::Rect')) {
699 croak "hash element of key '$key' is not an SDL::Rect-based object";
700 }
701
702 if ( _do_rects_intersect($self, $value) ) {
703 $collisions{$key} = $value;
704 }
705 }
706 return \%collisions;
707}
708
709
389e4b7b 71042;
711__END__
712
713=head1 NAME
714
715SDL::Game::Rect - SDL::Game object for storing and manipulating rectangular coordinates
716
717=head1 SYNOPSIS
718
719
720=head1 DESCRIPTION
721
722C<< 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 >>.
723
724All 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.
725
726
727=head2 ATTRIBUTES
728
729All Rect attributes are acessors, meaning you can get them by name, and set them by passing a value:
730
731 $rect->left(15);
732 $rect->left; # 15
733
734The Rect object has several attributes which can be used to resize, move and align the Rect.
735
736
737=over 4
738
739=item * width, w - gets/sets object's width
740
741=item * height, h - gets/sets object's height
742
743=item * left, x - moves the object left position to match the given coordinate
744
745=item * top, y - moves the object top position to match the given coordinate
746
747=item * bottom - moves the object bottom position to match the given coordinate
748
749=item * right - moves the object right position to match the given coordinate
750
751=item * centerx - moves the object's horizontal center to match the given coordinate
752
753=item * centery - moves the object's vertical center to match the given coordinate
754
755=back
756
757Some of the attributes above can be fetched or set in pairs:
758
759 $rect->topleft(10, 15); # top is now 10, left is now 15
760
761 my ($width, $height) = $rect->size;
762
763
764=over 4
765
766=item * size - gets/sets object's size (width, height)
767
768=item * topleft - gets/sets object's top and left positions
769
770=item * midleft - gets/sets object's vertical center and left positions
771
772=item * bottomleft - gets/sets object's bottom and left positions
773
774=item * center - gets/sets object's center (horizontal(x), vertical(y))
775
776=item * topright - gets/sets object's top and right positions
777
778=item * midright - gets/sets object's vertical center and right positions
779
780=item * bottomright - gets/sets object's bottom and right positions
781
782=item * midtop - gets/sets object's horizontal center and top positions
783
784=item * midbottom - gets/sets object's horizontal center and bottom positions
785
786=back
787
788
789=head2 METHODS
790
791Methods denoted as receiving Rect objects can receive either C<<SDL::Game::Rect>> or raw C<<SDL::Rect>> objects.
792
793=head3 new ($left, $top, $width, $height)
794
795Returns a new Rect object with the given coordinates. If any value is omitted (by passing undef), 0 is used instead.
796
797=head3 copy
798
799=head3 duplicate
800
801Returns a new Rect object having the same position and size as the original
802
803=head3 move(x, y)
804
805Returns a new Rect that is moved by the given offset. The x and y arguments can be any integer value, positive or negative.
806
807=head3 move_ip(x, y)
808
809Same as C<<move>> above, but moves the current Rect in place and returns nothing.
810
811=head3 inflate(x, y)
812
813Grows 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.
814
815=head3 inflate_ip(x, y)
816
817Same as C<<inflate>> above, but grows/shrinks the current Rect in place and returns nothing.
818
819=head3 clamp($rect)
820
821Returns 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.
822
823=head3 clamp_ip($rect)
824
825Same as C<<clamp>> above, but moves the current Rect in place and returns nothing.
826
827=head3 clip($rect)
828
74f8c259 829Returns 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 830
831=head3 clip_ip($rect)
832
74f8c259 833Same 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 834
835=head3 union($rect)
836
837Returns 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.
838
839=head3 union_ip($rect)
840
841Same as C<<union>> above, but resizes the current Rect in place and returns nothing.
842
843=head3 unionall( [$rect1, $rect2, ...] )
844
845Returns the union of one rectangle with a sequence of many rectangles, passed as an ARRAY REF.
846
847=head3 unionall_ip( [$rect1, $rect2, ...] )
848
849Same as C<<unionall>> above, but resizes the current Rect in place and returns nothing.
850
851=head3 fit($rect)
852
853Returns 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.
854
855=head3 fit_ip($rect)
856
857Same as C<<fit>> above, but moves/resizes the current Rect in place and returns nothing.
858
859=head3 normalize
860
861Corrects 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.
862
863=head3 contains($rect)
864
865Returns true (non-zero) when the argument is completely inside the Rect. Otherwise returns undef.
866
867=head3 collidepoint(x, y)
868
869Returns 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.
870
871=head3 colliderect($rect)
872
873Returns true (non-zero) if any portion of either rectangles overlap (except for the top+bottom or left+right edges).
874
875=head3 collidelist( [$rect1, $rect2, ...] )
876
877Test 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.
878
879=head3 collidelistall( [$rect1, $rect2, ...] )
880
881Returns 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.
882
883=head3 collidehash( {key1 => $rect1, key2 => $rect2, ...} )
884
885Receives 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).
886
887=head3 collidehashall( {key1 => $rect1, key2 => $rect2, ...} )
888
889Returns 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.
890
891
892=head1 AUTHOR
893
894Breno G. de Oliveira, C<< <garu at cpan.org> >>
895
896=head1 BUGS
897
898Please 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.
899
900
901=head1 SUPPORT
902
903You can find documentation for this module with the perldoc command.
904
905 perldoc SDL::Game::Rect
906
907
908=head1 ACKNOWLEDGEMENTS
909
910Many thanks to all SDL_Perl contributors, and to the authors of pygame.rect, in which this particular module is heavily based.
911
912=head1 COPYRIGHT & LICENSE
913
914Copyright 2009 Breno G. de Oliveira, all rights reserved.
915
916This program is free software; you can redistribute it and/or modify it
917under the same terms as Perl itself.
918
919
920=head1 SEE ALSO
921
922perl, L<SDL>, L<SDL::Rect>, L<SDL::Game>