Class cocos.collision_model.CollisionManager

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:

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:

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

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

Examples actors for this case are food, coins, trees, rocks.

Methods

  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

Method Details

remove_tricky

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. obj is required to be a known object.

iter_colliding

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. obj is not required to be a known object

Usage:

for other in collision_manager.iter_colliding(obj):
    # process event 'obj touches other'

objs_near

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. Notice that it includes the ones colliding with obj. obj is not required to be a known object

objs_near_wdistance

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. Notice that it includes the ones colliding with obj. obj is not required to be a known object If the game logic wants the list ordered by ascending distances, use ranked_objs_near instead.

iter_all_collisions

iter_all_collisions(self)
Iterator that exposes all collisions between known objects. At each step it will yield a pair (obj, other). If (obj1, obj2) is seen when consuming the iterator, then (obj2, obj1) will not be seen. In other worlds, 'obj1 collides with obj2' means (obj1, obj2) or (obj2, obj1) will appear in the iterator output but not both.

objs_touching_point

objs_touching_point(self, x, y)

Returns a container with known objects touching point (x, y)

Useful for mouse pick

objs_into_box

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

Useful for elastic box selection