cocos.mapcolliders module

Support for handling collisions between an actor and a container of objects

class RectMapCollider(velocity_on_bump=None)

Bases: object

Helper to handle collisions between an actor and objects in a RectMapLayer

Parameters:velocity_on_bump (str) – one of "bounce", "stick", "slide". selects which of the predefined on_bump handlers will be used
on_bump_handler

method to change velocity when a collision was detected

bumped_x

bool – True if collide_map detected collision in the x-axis

bumped_y

bool – True if collide_map detected collision in the y-axis

The code that updates actor position and velocity would call method collide_map() to account for collisions

There are basically two ways to include this functionality into an actor class

  • as a component, essentially passing (mapcollider, maplayer) in the actor’s __init__
  • mixin style, by using RectMapCollider or a subclass as a secondary base class for actor.

Component way is more decoupled, Mixin style is more powerful because the collision code will have access to the entire actor trough his ‘self’.

To have a working instance the behavior of velocity in a collision must be defined, and that’s the job of method on_bump_handler

  • if one of the stock on_bump_<variant> suits the requirements, suffices
    mapcollider.on_bump_handler = mapcollider.on_bump_<desired variant>
    or passing a selector at instantiation time
    mapcollider = MapCollider(<desired variant>)
  • for custom behavior define on_bump_handler in a subclass and instantiate it.
collide_bottom(obj)

placeholder, called when collision with obj’s bottom side detected

collide_left(obj)

placeholder, called when collision with obj’s left side detected

collide_map(maplayer, last, new, vx, vy)

Constrains a movement last -> new by considering collisions

Parameters:
  • maplayer (RectMapLayer) – layer with solid objects to collide with.
  • last (Rect) – actor rect before step.
  • new (Rect) – tentative rect after the stepm will be adjusted.
  • vx (float) – velocity in x-axis used to calculate ‘last’ -> ‘new’
  • vy (float) – velocity in y-axis used to calculate ‘last’ -> ‘new’
Returns:

(vx, vy) (float, float) – the possibly modified (vx, vy).

Assumes:

‘last’ does not collide with any object.

The dt involved in ‘last’ -> ‘new’ is small enough that no object can entirely fit between ‘last’ and ‘new’.

Side effects:
new eventually modified to not be into forbidden area. For each collision with one object’s side detected, the method self.collide_<side>(obj) is called.
if rect new does not overlap any object in maplayer, the method
  • does not modify new.
  • returns unchanged (vx, vy).
  • no method self.collide_<side> is called.
  • self.bumped_x and self.bumped_y both will be False.
if rect new does overlaps any object in maplayer, the method:
  • modifies new to be the nearest rect to the original new rect that it is still outside any maplayer object.
  • returns a modified (vx, vy) as specified by self.on_bump_handler.
  • after return self.bumped_x (resp self.bumped_y) will be True if an horizontal (resp vertical) collision happened.
  • if the movement from last to the original new was stopped by side <side> of object <obj>, then self.collide_<side>(obj) will be called.

Implementation details

Adjusts new in two passes against each object in maplayer.

In pass one, new is collision tested against each object in maplayer:
  • if collides only in one axis, new is adjusted as close as possible but not overlapping object
  • if not overlapping, nothing is done
  • if collision detected on both axis, let second pass handle it
In pass two, new is collision tested against the objects with double collisions in pass one:
  • if a collision is detected, adjust new as close as possible but not overlapping object, ie. use the smallest displacement on either X or Y axis. If they are both equal, move on both axis.
collide_right(obj)

placeholder, called when collision with obj’s right side detected

collide_top(obj)

placeholder, called when collision with obj’s top side detected

detect_collision(obj, last, new)

returns minimal correction in each axis to not collide with obj

Parameters:
  • obj – object in a MapLayer
  • last (Rect) – starting rect for the actor step
  • new (Rect) – tentative actor’s rect after step

Decides if there is a collision with obj when moving last -> new and then returns the minimal correctioin in each axis as to not collide.

It can be overridden to be more selective about when a collision exists (see the matching method in RectMapWithPropsCollider for example).

on_bump_bounce(vx, vy)

Bounces when a wall is touched.

Example use case: bouncing projectiles.

on_bump_handler(vx, vy)

Returns velocity after all collisions considered by collide_map

Parameters:
  • vx (float) – velocity in x-axis before collision
  • vy (float) – velocity in y-axis before collision
Returns:

(vx, vx) – velocity after all collisions considered in collide_map

This is a placeholder, either define a custom one or replace with one of the stock on_bump_<bump_style> methods

on_bump_slide(vx, vy)

Blocks movement only in the axis that touched a wall.

Example use case: player in a platformer game.

on_bump_stick(vx, vy)

Stops all movement when any wall is touched.

Example use case: sticky bomb, hook weapon projectile.

resolve_collision(obj, new, dx_correction, dy_correction)

Corrects new to just avoid collision with obj, does side effects.

Parameters:
  • obj (obj) – the object colliding with new.
  • new (Rect) – tentative actor position before considering collision with obj.
  • dx_correction (float) – smallest correction needed on new x position not to collide obj.
  • dy_correction (float) – smallest correction needed on
  • y position not to collide obj. (new) –

The correction is applied to new position.

If a collision along the x-axis (respectively y-axis) was detected, the flag self.bumped_x (resp y) is set.

If the movement towards the original new was stopped by side <side> of object <obj>, then self.collide_<side>(obj) will be called.

class RectMapWithPropsCollider(velocity_on_bump=None)

Bases: cocos.mapcolliders.RectMapCollider

Helper to handle collisions between an actor and objects in a RectMapLayer

Same as RectMapCollider except that collision detection is more fine grained. Collision happens only on objects sides with prop(<side>) set.

Look at RectMapCollider for details

detect_collision(obj, last, new)

Returns minimal correction in each axis to not collide with obj

Collision happens only on objects sides with prop <side> set.

class TmxObjectMapCollider(velocity_on_bump=None)

Bases: cocos.mapcolliders.RectMapCollider

Helper to handle collisions between an actor and objects in a TmxObjectLayer

Same as RectMapCollider except maplayer is expected to be a TmxObjectLayer, so the objects to collide are TmxObject instances.

Look at RectMapCollider for details

collide_map(maplayer, last, new, vx, vy)

Constrains a movement last -> new by considering collisions

Parameters:
  • maplayer (RectMapLayer) – layer with solid objects to collide with.
  • last (Rect) – actor rect before step.
  • new (Rect) – tentative rect after the stepm will be adjusted.
  • vx (float) – velocity in x-axis used to calculate ‘last’ -> ‘new’
  • vy (float) – velocity in y-axis used to calculate ‘last’ -> ‘new’
Returns:

vx, vy (float, float) – the possibly modified (vx, vy).

See RectMapCollider.collide_map() for side effects and details

make_collision_handler(collider, maplayer)

Returns f = collider.collide_map(maplayer, ...)

Returns:f(last, new, vx, vy) -> (vx, vy)

Utility function to create a collision handler by combining

Parameters:
  • maplayer – tells the objects to collide with.
  • collider – tells how velocity changes on collision and resolves actual collisions.