One of the benefits of the physics engine is that it frees us from handling gravity and its effects on falling and jumping in our own code; these are well-understood, well-established procedures, and coding them again ourselves makes no sense when there are already high-performance, well-tested tools available. However, as players of platform games, we frequently want to be able to reach certain high areas without having to jump up complicated staircases first. To create a ladder that we can both walk past and climb up, some special code is needed to interact with the gravity system; we'll practice detecting when the player is in a suitable place to change its physics (that is touching a ladder) by using a sensor object.
There is one limitation of Corona's current implementation of Box2D that will oblige us to do a bit of work on our own. There is currently no way to ask what other objects a sensor or body is currently in contact with, so we have to remember objects when we start a collision with them, and then forget them when the collision is over.
Open character/init.lua
and add a table to store objects the character is in contact with:
self.Speed = kind.Speed
self.Adjacent = {}
self.Brain = enlighten(self)
In the collision processor, register any object in this table that starts a collision with the character.
local function touch(event)
local self, other = event.target, event.other
if event.phase == 'began' then
self.Adjacent[other] = other
if other.Name == 'Ground' then
When a collision ends, remove the departing object from the character's list.
elseif event.phase == 'ended' then
self.Adjacent[other] = nil
if other.Climbable then
When the player controller gets a climb input, it needs to check whether there is a ladder available. Open game.lua
and add an adapting listener when the Player
object is created:
UI:addEventListener('Release', self.Player.Mind) UI:addEventListener('Vertical', self.Player) function self.Player:Vertical(event) for object in pairs(self.Adjacent) do if object.Climbable then self:dispatchEvent{name = 'Climb'; unpack(event)} break end end end self.Focus = self.Player
Return to character/init.lua
and locate the presence.climb
function inside the enlighten
function. When the climbing process starts, reduce the effect of gravity on the character to nothing, to represent it holding on.
function presence.climb(direction)
local action
character.gravityScale = 0
repeat
local elapsed
3.138.113.188