Collisions _____________ Collide with ************ Rigid body ---------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body`. Any existing rigid body name or *ANYBODY* can be specified. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body`. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(COLLISION, system.evtHandler, rectangle1, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(COLLISION, applyImpulse, other=rectangle1, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def applyImpulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(COLLISION, applyImpulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(COLLISION, applyImpulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Rigid body type ---------------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body type `. *ANYCIRCLE*, *ANYRECTANGLE*, *ANYPOLYGON*, and *ANYBODY* are the valid type constants that can be used to specify the type of rigid body that could trigger the given action. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body`. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(COLLISION, system.evtHandler, RECTANGLE, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(COLLISION, applyImpulse, other=ANYRECTANGLE, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. In this case we could also use *ANYCIRCLE*, *ANYPOLYGON*, or *ANYBODY*. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def apply_impulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(COLLISION, apply_impulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(COLLISION, apply_impulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Walls ------ This condition is satisfied if the :term:`bound element` collides with the specified :term:`wall`. *system.bottomWall*, *system.rightWall*, *system.topWall*, *system.leftWall*, or *ANYWALL* can be used to define the condition. If *ANYWALL* is specifed then the condition is satisfied if the bound element collides with any of the four system walls. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Constrain polygon1's rotational motion when polygon1 collides with system.leftWall. polygon1.bind(COLLISION, system.evtHandler, system.bottomWall, CONSTRAINROTATION) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def constrain_rotation(event, source, other=system.bottomWall): source.fixedRotation = True polygon1.bind(COLLISION, constrain_rotation, other=system.bottomWall) Projectile ---------- This condition is satisfied if the :term:`bound element` collides with a :term:`projectile`. This is usually used for shooting games. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Destroy polygon2 when polygon2 collides with PROJECTILE. polygon2.bind(COLLISION, system.evtHandler, PROJECTILE, DESTROY) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def destroy(event, source): system.destroy(source) polygon2.bind(COLLISION, destroy, PROJECTILE) Anything --------- This condition is satisfied if the :term:`bound element` collides with a wall, rigid body or projectile. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Move towards OTHER with vel = 5 when circle1 collides with ANYTHING. circle1.bind(COLLISION, system.evtHandler, ANYTHING, MOVETOWARDS, **{'towards': OTHER, 'velocity': 5}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def move_towards(event, source, velocity): #find the object that collided with the source body1 = event.shape1.GetUserData() body2 = event.shape2.GetUserData() if body1 == source: towards = body2 else: towards = body1 #find the direction direction = pyB2D.b2Vec2(towards.x - source.x, towards.y - source.y) #normalize the direction vector direction.Normalize() #multiply it by the velocity magnitude velocity_vector = direction * velocity source.vx = velocity_vector.x source.vy = velocity_vector.y circle1.bind(COLLISION, move_towards, ANYTHING, velocity=5) Touching ********* This condition is satisfied when the :term:`bound element` is in steady contact with the specified element. Similar to the collision event, a rigid body, can be touching another rigid body, rigid body type or wall. Rigid body ---------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body`. Any existing rigid body name or *ANYBODY* can be specified. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body`. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(TOUCHING, system.evtHandler, rectangle1, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(TOUCHING, applyImpulse, other=rectangle1, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def applyImpulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(TOUCHING, applyImpulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(TOUCHING, applyImpulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Rigid body type ---------------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body type `. *ANYCIRCLE*, *ANYRECTANGLE*, *ANYPOLYGON*, and *ANYBODY* are the valid type constants that can be used to specify the type of rigid body that could trigger the given action. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body `. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(TOUCHING, system.evtHandler, RECTANGLE, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(TOUCHING, applyImpulse, other=ANYRECTANGLE, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. In this case we could also use *ANYCIRCLE*, *ANYPOLYGON*, or *ANYBODY*. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def apply_impulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(TOUCHING, apply_impulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(TOUCHING, apply_impulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Walls ------ This condition is satisfied if the :term:`bound element` collides with the specified :term:`wall`. *system.bottomWall*, *system.rightWall*, *system.topWall*, *system.leftWall*, or *ANYWALL* can be used to define the condition. If *ANYWALL* is specifed then the condition is satisfied if the bound element collides with any of the four system walls. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Constrain polygon1's rotational motion when polygon1 collides with system.leftWall. polygon1.bind(TOUCHING, system.evtHandler, system.bottomWall, CONSTRAINROTATION) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def constrain_rotation(event, source, other=system.bottomWall): source.fixedRotation = True polygon1.bind(TOUCHING, constrain_rotation, other=system.bottomWall) Projectile ---------- This condition is satisfied if the :term:`bound element` collides with a :term:`projectile`. This is usually used for shooting games. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Destroy polygon2 when polygon2 collides with PROJECTILE. polygon2.bind(TOUCHING, system.evtHandler, PROJECTILE, DESTROY) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def destroy(event, source): system.destroy(source) polygon2.bind(TOUCHING, destroy, PROJECTILE) Anything --------- This condition is satisfied if the :term:`bound element` collides with a wall, rigid body or projectile. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Move towards OTHER with vel = 5 when circle1 collides with ANYTHING. circle1.bind(TOUCHING, system.evtHandler, ANYTHING, MOVETOWARDS, **{'towards': OTHER, 'velocity': 5}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def move_towards(event, source, velocity): #find the object that collided with the source body1 = event.shape1.GetUserData() body2 = event.shape2.GetUserData() if body1 == source: towards = body2 else: towards = body1 #find the direction direction = pyB2D.b2Vec2(towards.x - source.x, towards.y - source.y) #normalize the direction vector direction.Normalize() #multiply it by the velocity magnitude velocity_vector = direction * velocity source.vx = velocity_vector.x source.vy = velocity_vector.y circle1.bind(TOUCHING, move_towards, ANYTHING, velocity=5) Disconnect from **************** This condition is satisfied when the :term:`bound element` is detached from the specified element. This could occur after a collision or steady contact. Rigid body ---------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body`. Any existing rigid body name or *ANYBODY* can be specified. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body`. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(DISCONNECT, system.evtHandler, rectangle1, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(DISCONNECT, applyImpulse, other=rectangle1, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def applyImpulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(DISCONNECT, applyImpulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(DISCONNECT, applyImpulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Rigid body type ---------------- This condition is satisfied if the :term:`bound element` collides with the specified :term:`rigid body type `. *ANYCIRCLE*, *ANYRECTANGLE*, *ANYPOLYGON*, and *ANYBODY* are the valid type constants that can be used to specify the type of rigid body that could trigger the given action. If ANYBODY is specified then the condition is satisfied if the bound element collides with any :term:`rigid body`. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Apply impulse to polygon2 when circle1 collides with rectangle1. circle1.bind(DISCONNECT, system.evtHandler, RECTANGLE, APPLYIMPULSE, **{'target': polygon2, 'ix': 10, 'iy': 10, 'bx': 0, 'by': 0}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def applyImpulse(event, source, target): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(DISCONNECT, applyImpulse, other=ANYRECTANGLE, target=polygon2) ``other``: Element the :term:`bound element` needs to collide with in order to trigger the specified action. In this case we could also use *ANYCIRCLE*, *ANYPOLYGON*, or *ANYBODY*. ``target``: Element that action is applied to. By specifying the ix, iy, bx, and by values, *applyImpulse* function can be made more flexible as shown below. This way, the same function can be used by many similar behavior definitions. This keeps the code size smaller and makes maintaining the code easier. .. code-block:: python def apply_impulse(event, source, target, ix, iy, bx, by): target.applyImpulse(ix=10, iy=10, bx=0, by=0) circle1.bind(DISCONNECT, apply_impulse, other=rectangle1, target=polygon2, ix=10, iy=10, bx=0, by=0) circle2.bind(DISCONNECT, apply_impulse, other = rectangle2, target=polygon2, ix = -5, iy = 5, bx=0, by=0) Walls ------ This condition is satisfied if the :term:`bound element` collides with the specified :term:`wall`. *system.bottomWall*, *system.rightWall*, *system.topWall*, *system.leftWall*, or *ANYWALL* can be used to define the condition. If *ANYWALL* is specifed then the condition is satisfied if the bound element collides with any of the four system walls. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Constrain polygon1's rotational motion when polygon1 collides with system.leftWall. polygon1.bind(DISCONNECT, system.evtHandler, system.bottomWall, CONSTRAINROTATION) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def constrain_rotation(event, source, other=system.bottomWall): source.fixedRotation = True polygon1.bind(DISCONNECT, constrain_rotation, other=system.bottomWall) Projectile ---------- This condition is satisfied if the :term:`bound element` collides with a :term:`projectile`. This is usually used for shooting games. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Destroy polygon2 when polygon2 collides with PROJECTILE. polygon2.bind(DISCONNECT, system.evtHandler, PROJECTILE, DESTROY) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def destroy(event, source): system.destroy(source) polygon2.bind(DISCONNECT, destroy, PROJECTILE) Anything --------- This condition is satisfied if the :term:`bound element` collides with a wall, rigid body or projectile. Automatically generated code (generated by the :term:`behavior dialog`): .. code-block:: python # Move towards OTHER with vel = 5 when circle1 collides with ANYTHING. circle1.bind(DISCONNECT, system.evtHandler, ANYTHING, MOVETOWARDS, **{'towards': OTHER, 'velocity': 5}) Manually created code (equivalent to the automatically generated code shown above): .. code-block:: python def move_towards(event, source, velocity): #find the object that collided with the source body1 = event.shape1.GetUserData() body2 = event.shape2.GetUserData() if body1 == source: towards = body2 else: towards = body1 #find the direction direction = pyB2D.b2Vec2(towards.x - source.x, towards.y - source.y) #normalize the direction vector direction.Normalize() #multiply it by the velocity magnitude velocity_vector = direction * velocity source.vx = velocity_vector.x source.vy = velocity_vector.y circle1.bind(DISCONNECT, move_towards, ANYTHING, velocity=5)