Breno G. de Oliveira

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 the Collision::Util function you want.

  • "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 ).

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:

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.