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
¶ True if collide_map detected collision in the x-axis
- Type
bool
-
bumped_y
¶ True if collide_map detected collision in the y-axis
- Type
bool
The code that updates actor position and velocity would call method
collide_map()
to account for collisionsThere 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 methodself.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
andself.bumped_y
both will beFalse
.
- if rect
new
does overlaps any object in maplayer, the method: modifies
new
to be the nearest rect to the originalnew
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 originalnew
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 objectif 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
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 collideobj
.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>, thenself.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.