Collision::Util - A selection of general collision detection utilities
Say you have a class with ->x(), ->y(), ->w(), and ->h() accessors, like SDL::Rect or the one below:
->x()
->y()
->w()
->h()
package Block; use Class::XSAccessor { constructor => 'new', accessors => [ 'x', 'y', 'w', 'h' ], };
let's go for a procedural approach:
use Collision::Util ':std'; my $rect1 = Block->new( x => 1, y => 1, w => 10, h => 10 ); my $rect2 = Block->new( x => 5, y => 9, w => 6, h => 4 ); my $rect3 = Block->new( x => 16, y => 12, w => 3, h => 3 ); check_collision($rect1, $rect2); # true check_collision($rect3, $rect1); # false # you can also check them all in a single run: check_collision($rect1, [$rect2, $rect3] );
As you might have already realized, you can just as easily bundle collision detection into your objects:
package CollisionBlock; use Class::XSAccessor { constructor => 'new', accessors => [ 'x', 'y', 'w', 'h' ], }; # if your class has the (x, y, w, h) accessors, # imported functions will behave just like methods! use Collision::Util ':std';
Then, further in your code:
my $rect1 = CollisionBlock->new( x => 1, y => 1, w => 10, h => 10 ); my $rect2 = CollisionBlock->new( x => 5, y => 9, w => 6, h => 4 ); my $rect3 = CollisionBlock->new( x => 16, y => 12, w => 3, h => 3 ); $rect1->check_collision( $rect2 ); # true $rect3->check_collision( $rect1 ); # false # you can also check if them all in a single run: $rect1->check_collision( [$rect2, $rect3] );
Collision::Util contains sets of several functions to help you detect collisions in your programs. While it focuses primarily on games, you can use it for any application that requires collision detection.
Collision::Util doesn't export anything by default. You have to explicitly define function names or one of the available helper sets below:
exports check_collision() and check_contains().
check_collision()
check_contains()
exports check_collision_rect() and check_contains_rect().
check_collision_rect()
check_contains_rect()
TODO
exports all functions.
if ( check_contains($ball, $goal) ) { # SCORE !! } die if check_contains($hero, \@bullets);
Returns the index (starting from 1, so you always get a 'true' value) of the first target item completely inside $source. Otherwise returns undef.
my @visible = check_contains($area, \@enemies);
If your code context wants it to return a list, inside will return a list of all indices (again, 1-based) completely inside $source. If no elements are found, an empty list is returned.
inside
my @names = check_contains($track, \%horses);
Similarly, you can also check which (if any) elements of a hash are inside your element, which is useful if you group your objects like that instead of in a list.
if ( check_collision($player, $wall) ) { # ouch } die if check_collision($hero, \@lava_pits);
Returns the index (starting from 1, so you always get a 'true' value) of the first target item that collides with $source. Otherwise returns undef.
my @hits = check_collision($planet, \@asteroids);
If your code context wants it to return a list, inside will return a list of all indices (again, 1-based) that collide with $source. If no elements are found, an empty list is returned.
my @keys = check_collision($foo, \%bar);
Similarly, you can also check which (if any) elements of a hash are colliding with your element, which is useful if you group your objects like that instead of in a list.
TODO (but SYNOPSIS should give you a hint)
"must receive a target"
You tried calling the function without a target. Remember, syntax is always foo($source, $target), or, if you're not using it directly and the collision is a method inside object $source, then it's $source->foo($target). Here of course you should replace foo with the name of the Collision::Util function you want.
foo($source, $target)
$source
Collision::Util
"elements should have x, y, w, h accessors"
Both $source and $target must be objects with accessors for x (left coordinate ), y (top coordinate ), w (object's width ), and h (object's height ).
$target
x
y
w
h
Breno G. de Oliveira, <garu at cpan.org>
<garu at cpan.org>
Many thanks to Kartik Thakore for his help and insights.
Please report any bugs or feature requests to bug-collision-util at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Collision-Util. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-collision-util at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Collision::Util
You can also look for information at:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Collision-Util
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Collision-Util
CPAN Ratings
http://cpanratings.perl.org/d/Collision-Util
Search CPAN
http://search.cpan.org/dist/Collision-Util/
Copyright 2010 Breno G. de Oliveira.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
To install Collision::Util, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Collision::Util
CPAN shell
perl -MCPAN -e shell install Collision::Util
For more information on module installation, please visit the detailed CPAN module installation guide.