cocos.collision_model module

class AARectShape(center, half_width, half_height)

Bases: object

Implements the Cshape interface that uses rectangles with sides parallel to the coordinate axis as geometric shape.

Distance is not the euclidean distance but the rectangular or max-min distance, max( min(x0 - x1), min(y0 - y1) : (xi, yi) in recti )

Good if actors don’t rotate.

Look at Cshape for other class and methods documentation.

copy()
distance(other)
fits_in_box(packed_box)
minmax()
near_than(other, near_distance)
overlaps(other)
touches_point(x, y)
class CircleShape(center, r)

Bases: object

Implements the Cshape interface that uses discs as geometric shape.

Distance is the euclidean distance.

Look at Cshape for other class and methods documentation.

copy()
distance(other)
fits_in_box(packed_box)
minmax()
near_than(other, near_distance)
overlaps(other)
touches_point(x, y)
class CollisionManager

Bases: object

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.

While usually all collidables in a collision manager are of the same class (CircleShape or AARectShape) it is allowed to use both types into the same collision manager.

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(obj)

Makes obj a know entity

any_near(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

clear()

Empties the known set

iter_all_collisions()

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.

iter_colliding(obj)

A lazy iterator over objects colliding with obj, allows to spare some CPU when the loop processing the collisions breaks before exhausting 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'
known_objs()

Returns a set with all the objects known by the CollisionManager Used for debug and testing.

knows(obj)

Returns True if obj was added to the collision manager, false otherwise Used for debug and testing.

objs_colliding(obj)

Returns a container with known objects that overlaps obj, excluding obj itself obj is not required to be a known object

objs_into_box(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

objs_near(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(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.

objs_touching_point(x, y)

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

Useful for mouse pick

ranked_objs_near(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

remove_tricky(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.

they_collide(obj1, obj2)

Returns a boolean, True if obj1 overlaps objs2 obj1, obj2 are not required to be known objects

class CollisionManagerBruteForce

Bases: object

Implements the CollisionManager interface with with the simpler code possible.

Intended for reference and debugging, it has very bad performance.

Look at CollisionManager for other class and methods documentation.

add(obj)
any_near(obj, near_distance)
clear()
iter_all_collisions()
iter_colliding(obj)
known_objs()
knows(obj)
objs_colliding(obj)
objs_into_box(minx, maxx, miny, maxy)
objs_near(obj, near_distance)
objs_near_wdistance(obj, near_distance)
objs_touching_point(x, y)
ranked_objs_near(obj, near_distance)
remove_tricky(obj)
they_collide(obj1, obj2)
class CollisionManagerGrid(xmin, xmax, ymin, ymax, cell_width, cell_height)

Bases: object

Implements the CollisionManager interface based on the scheme known as spatial hashing.

The idea behind is to divide the space in rectangles with a given width and height, and have a table telling which objects overlaps each rectangle.

Later, when the question ‘which know objects has such and such spatial relation with <some object>’ arrives, only the objects in rectangles overlapping <some object> (or nearby ones) needs to be examined for the condition.

Look at CollisionManager for other class and methods documentation.

add(obj)
any_near(obj, near_distance)
clear()
iter_all_collisions()
iter_colliding(obj)
known_objs()
knows(obj)
objs_colliding(obj)
objs_into_box(minx, maxx, miny, maxy)
objs_near(obj, near_distance)
objs_near_wdistance(obj, near_distance)
objs_touching_point(x, y)
ranked_objs_near(obj, near_distance)
remove_tricky(obj)
they_collide(obj1, obj2)
class Cshape

Bases: object

Represents an abstract geometric shape in the 2D space, and can answer questions about proximity or intersection with other shapes.

Implementations are free to restrict the type of geometrical shapes that will accept, by example circles or axis aligned rectangles.

copy()

Returns a copy of itself

Return type:Cshape
distance(other)

Returns a float, distance from itself to other;

Not necessarily euclidean distance. It is distances between boundaries.

Return type:float
fits_in_box(packed_box)

Returns a boolean, True if the shape fully fits into the axis aligned rectangle defined by packed_box, False otherwise.

Parameters:
packed_box
: 4-tuple floats

An axis aligned rectangle expressed as (minx, maxx, miny, maxy)

Return type:

bool

minmax()

Returns the smallest axis aligned rectangle that contains all shape points.

The rectangle is expressed as a 4-tuple of floats (minx, maxx, miny, maxy) Such a rectangle is also know as the Axis Aligned Bounding Box for shape; AABB for short.

Return type:4-tuple of floats
near_than(other, near_distance)

Returns a boolean, True if distance(self, other)<=near_distance

Return type:bool
overlaps(other)

Returns True if overlapping other, False otherwise

Return type:bool
touches_point(x, y)

Returns True if the point (x,y) overlaps the shape, False otherwise

Return type:bool
aa_rect_distance_aa_rect(aa_rect, other)

Give the distance between two axis-aligned rectangles.

The rect must have members ‘center’, ‘rx’, ‘ry’ where the latest two are the rect half_width and half_height.

aa_rect_distance_circle(aa_rect, circle)

Give the distance between an axis-aligned rectangle and a circle.

The rect must have members ‘center’, ‘rx’, ‘ry’ where the latest two are the rect half_width and half_height. The circle must have members ‘center’, ‘r’, where the latest is the radius.

aa_rect_overlaps_aa_rect(aa_rect, other)

Tells if two axis aligned rectangles overlap.

The rects must have members ‘center’, ‘rx’, ‘ry’ where the latest two are the rect half_width and half_height.

aa_rect_overlaps_circle(aa_rect, circle)

Tells if an axis aligned rectangle and a circle overlap.

The rect must have members ‘center’, ‘rx’, ‘ry’ where the latest two are the rect half_width and half_height. The circle must have members ‘center’, ‘r’, where the latest is the radius.

circle_distance_circle(circle, other)

Give the distance between two circles.

The circles must have members ‘center’, ‘r’, where the latest is the radius.

circle_overlaps_circle(circle, other)

Tells if two circles overlap.

The circles must have members ‘center’, ‘r’, where the latest is the radius.

clamp(value, minimum, maximum)