Trees | Indices | Toggle frames |
---|
Answers questions about proximity or collision with known objects.
After instantiation or after calling its 'clear' method the instance don't knows any object.
An object is made known to the CollisionManager instance by calling its 'add' method with the object instance.
Example questions are:
- which known objects collides with <this object> ?
- which known objects are near than 6.0 from <this object> ?
Note that explicit objects in the question (call) don't need to be known to the collision manager answering the question. If the explicit object indeed is known, then it is omitted in the answer as a trivial case.
There can be multiple CollisionManager instances in the same scope, and an object can be known to many collision managers at the same time.
Objects that can be known or can be presented to a Collision Manager in a question must comply with:
- obj has a member called cshape
- obj.cshape supports the interface Cshape
Such an object can be called 'a collidable' in the documentation, and when 'obj' or 'other' is seen in the code you can assume it means collidable.
As a limitation imposed by the current Cshapes implementations, all the collidables that interacts with a particular instance of CollisionManager must share the same concrete Cshape subclass: by example, all objects should have a CircleShape cshape, or all objects should have a AARectShape cshape.
The known objects collective for each CollisionManager instance is manipulated by calling the methods
- clean() : forgets all objects and empties internal data structures
- add(obj) : remember obj as a known object
- remove_tricky(obj) : forgets obj
When objects are made known to a collision manager, internal data structures are updated based on the obj.cshape value at the 'add' moment. In particular, the obj.cshape indirectly tells where in the internal structures certain info will be stored. Later, the internal data structures are used to accelerate answers.
This means that modifying obj.cshape after an 'add' can produce a memory leak in the next 'remove_tricky', and that in the same situation some answers can be partially wrong. What type of wrong ? It can sometimes miss a collision with a know object that changed it cshape.
It is user code responsibility to drive the know objects update when obj.cshape values changes.
Common use patterns that are safe and efficient:
When most of the known objects update cshape each frame
You do:
# updating collision info collision_manager.clear() # fast, no leaks even if changed cshapes for actor in moving_actors: collision_manager.add(actor) # game logic # do what you need, but defer changes in cshape to next block # by example for actor in moving_actors: actor.new_pos = actor.cshape.center + dt * vel #other logic that potentially needs collision info; #it will be accurate because you have not changed cshapes ... # update cshapes for next frame for actor in moving actors: actor.cshape.center = actor.new_pos
Example actors for this case are player, enemies, soldiers.
All of the known objects don't change cshapes
- At level start you add all objects
- When an actor reaches end of life use 'remove_tricky' to make it not known, no problem because his cshape has not changed
Examples actors for this case are food, coins, trees, rocks.
add(self,
obj)
Makes obj a know entity
|
|
remove_tricky(self,
obj)
(obj should have the same .cshape value that when added)
Makes collision manager forget about obj, thus no further query will
return obj.
|
|
clear(self)
Empties the known set
|
|
they_collide(self,
obj1,
obj2)
Returns a boolean, True if obj1 overlaps objs2
obj1, obj2 are not required to be known objects
|
|
objs_colliding(self,
obj)
Returns a container with known objects that overlaps obj,
excluding obj itself
obj is not required to be a known object
|
|
iter_colliding(self,
obj)
A lazy iterator over objects colliding with obj, allows to spare some
CPU when the loop procesing the colissions breaks before exausting
the collisions.
|
|
any_near(self,
obj,
near_distance)
Returns None if no know object (except itself) is near than
near_distance, else an arbitrary known object with distance
less than near_distance
obj is not required to be a known object
|
|
objs_near(self,
obj,
near_distance)
Returns a container with the objects known by collision manager that
are at distance to obj less or equal than near_distance, excluding
itself.
|
|
objs_near_wdistance(self,
obj,
near_distance)
Returns a list with the (other, distance) pairs that with all the
known objects at distance less or equal than near_distance to obj,
except obj itself.
|
|
ranked_objs_near(self,
obj,
near_distance)
Same as objs_near_wdistance but the list is ordered in increasing distance
obj is not required to be a known object
|
|
iter_all_collisions(self)
Iterator that exposes all collisions between known objects.
|
|
knows(self,
obj)
Returns True if obj was added to the collision manager, false otherwise
Used for debug and testing.
|
|
known_objs(self)
Reurns a set with all the objects known by the CollisionManager
Used for debug and testing.
|
|
objs_touching_point(self,
x,
y)
Returns a container with known objects touching point (x, y)
|
|
objs_into_box(self,
minx,
maxx,
miny,
maxy)
Returns a container with know objects that fully fits into the axis
aligned rectangle defined by params
|
A lazy iterator over objects colliding with obj, allows to spare some CPU when the loop procesing the colissions breaks before exausting the collisions. obj is not required to be a known object
Usage:
for other in collision_manager.iter_colliding(obj): # process event 'obj touches other'
Returns a container with known objects touching point (x, y)
Useful for mouse pick
Returns a container with know objects that fully fits into the axis aligned rectangle defined by params
Useful for elastic box selection
Trees | Indices | Toggle frames |
---|
Generated by Epydoc 3.0beta1 on Wed Oct 26 10:00:13 2011 | http://epydoc.sourceforge.net |