NAME
Collision::Util - A selection of general collision detection utilities
SYNOPSIS
Say you have a class with ->x()
, ->y()
, ->w()
, and ->h()
accessors, like SDL::Rect or the one below:
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] );
DESCRIPTION
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.
EXPORTABLE SETS
Collision::Util doesn't export anything by default. You have to explicitly define function names or one of the available helper sets below:
:std
exports check_collision()
and check_contains()
.
:rect
exports check_collision_rect()
and check_contains_rect()
.
:circ
TODO
:dot
TODO
:all
exports all functions.
MAIN UTILITIES
check_contains ($source, $target)
check_contains ($source, [$target1, $target2, $target3, ...])
check_contains ($source, { key1 => $target1, key2 => $target2, ...})
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.
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.
check_collision ($source, $target)
check_collision ($source, [$target1, $target2, $target3, ...])
check_collision ($source, { key1 => $target1, key2 => $target2, ...})
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.
USING IT IN YOUR OBJECTS
TODO (but SYNOPSIS should give you a hint)
DIAGNOSTICS
"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 theCollision::Util
function you want."elements should have x, y, w, h accessors"
Both
$source
and$target
must be objects with accessors forx
(left coordinate ),y
(top coordinate ),w
(object's width ), andh
(object's height ).
AUTHOR
Breno G. de Oliveira, <garu at cpan.org>
ACKNOWLEDGEMENTS
Many thanks to Kartik Thakore for his help and insights.
BUGS
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.
SUPPORT
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
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
LICENSE AND COPYRIGHT
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.