Almost every developer who uses Corona’s
For those developers who need even more specialized collision handling, Corona also features the pre-collision listener. This is reserved for specific, dedicated handling of a collision before it occurs and it’s often used with the PhysicsContact as discussed in the Multi-Element Collisions tutorial.
Yet a third option — less known but equally important in some cases — is the post-collision listener. As the name indicates, this listener is used to gather various details of a collision after it occurs. This event also provides some physical information that no other event type provides, making it especially useful in certain cases!
This tutorial won’t go into extensive detail on how to set up collision listeners since it’s all outlined in the Collision Detection guide. Basically,
-- Set up physics engine local physics = require( "physics" ) physics.start() -- Create a basic physics object local box = display.newRect( 60, 20, 50, 50 ) physics.addBody( box ) -- Set up the post-collision listener function local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) end -- Associate the listener function with the object box.postCollision = postCollisionEvent box:addEventListener( "postCollision" )
Be aware that
box:removeEventListener( "postCollision" ) box.postCollision = nil
It may seem pointless to gather details about a collision “after the fact” since the collision has already occurred and the physics engine has essentially moved to the next time step. However, it’s exactly the instances where
Let’s explore some potential instances where
The event.force
in the
local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) print( "FORCE:", event.force ) end
Where might this apply in a physics simulation? Consider the classic hit Angry Birds™ where each ornery avian has a different effect on different solid materials in the world — for example, the small blue birds strike particulary hard against “glass” blocks. If we were to implement similar game functionality, it would be easy to code a conditional check which detects if a blue bird collides with a glass block, but that limits us to a true/false relationship — we still wouldn’t know exactly what force was delivered in the collision. Using the
Collision forces are equally useful in “filtering” purposes. Consider a game where the player fires arrows at an armored enemy, for instance the armored skeleton in the Multi-Element Collisions tutorial. In theory, the skeleton’s armor has a certain threshold upon which it will block projectiles entirely, causing them to bounce off and fall to the ground. As noted above, a normal collision event can reveal that a projectile hit the skeleton, but it cannot provide details about collision force. Thus, the
The event.friction
in the
local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) print( "FRICTION:", event.friction ) end
Where might this apply in a physics simulation? One example would be to detect the friction of a car or other object when it collides with a metal surface, then use that value to display a variable amount of “sparks” via a particle emitter or other means. For example, if the friction is very high, we could generate a more visible amount of sparks, while if the friction is low — for instance the object just barely brushed against the surface — we could generate just a small burst of sparks (or even use the filtering threshold discussed above to omit the effect entirely).
Hopefully this tutorial has outlined some valid applications for post-collision events. While detecting these will never be as common as detecting normal collisions, they are unique events which can be essential to certain game logic and even to visual realism in a game.