Collision Handling Basics
When two objects collide, it may be desirable to run some Lua code. For example, when a ball hits a wall, you might want to play a "boing" sound. To make things happen when objects collide, you will need a collision handler.
Note: if SceneObject:setCollidable(false) is set on either object, neither the collision handler on the object with setCollidable(false) or the object it's hitting will call their collision handler. setCollidable(false) effectively drops out all collision checking from that object, so it is as if the object doesn't exist in the collision system at all. If you would like objects to pass through each other, but still call collision handlers when they do, see
Collision is NOT Instantaneous
Before we tell you how collision handlers work, we need to explain what collisions actually are: two objects that have very slightly penetrated each other. As soon as the two objects interpenetrate, the physics system starts applying forces to shove the two objects apart. But it may take a little time for the forces to cause the two objects to separate. Because of this, collisions actually have three stages:
- start: the objects have just interpenetrated each other.
- continue: the objects have been interpenetrating for a while, and the physics system is still trying to shove them apart.
- end: the physics system has finally succeeded in pushing the objects apart. They are no longer interpenetrating.
This is important: you need to remember that collision is not an instantaneous process - it can take quite a bit of time, in computer terms.
Collision Handlers
A collision handler is a Lua function that gets called when two objects collide. It takes three arguments: the first object (the object which has the collision handler set), the second object (the object against which it is colliding), and the stage, as described above. The stage is a string which can be "start", "continue", or "end".
The collision handler must be attached to a particular object using setCollisionHandler. Here is a simple example, which causes a ball to play a sound when it collides with something:
function boingCollisionFunction(obj1, obj2, stage)
if (stage == "start") then
Sound.new("alice/boing"):play()
end
end
ball:setCollisionHandler(boingCollisionFunction)
In a typical collision, the collision handling function will get called many times: once at the start of the collision, several times during the continuation of the collision, and once at the end of the collision. But we only want the 'boing' sound to get played once, so we check the 'stage' parameter. We only play the sound at the start of the collision.
One Collision, Two Handlers
When two objects collide, if both objects have collision handlers, then both collision handlers will get called. It is not predictable what order the handlers will get called in.
Sometimes, the two collision handlers may produce twice the effect you desire. For example, consider a billiards table where each ball has a collision handler that makes a "click" sound. When two balls collide, the two handlers will get called, and you'll get two clicks --- not what you want.
In this case, the solution is to use a rule to disable one of the two clicks. A good rule in this case would be for the collision handler of the higher numbered ball to make the click-sound, and the collision handler for the lower-numbered ball to stay silent:
function billiardBallCollisionHandler(obj1, obj2, stage)
if (stage == "start") then
if (obj1.ballNumber > obj2.ballNumber) then
Sound.new("alice/click"):play()
end
end
end
In fact, as a convenience feature, all SceneObjects can be compared against each other with <, <=, >, >=, and == operators and will return mathematically consistent answers (i.e. if objectA > objectB is true, objectB < objectA is also true). This feature can be useful in writing collision handlers similar to the one above.
Pass-Through
When two objects interpenetrate, the physics engine immediately applies forces to push them apart. If a collision handler calls the method SceneObject:passThrough, this will suppress these separation forces. Effectively, this will cause the two objects to pass through each other like ghosts.
- Printer-friendly version
- Login or register to post comments
-



