Controlling gravity to enable climbing

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.

Getting on with it

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.

Tracking contact with ladder regions

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

Detecting available ladders

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

Negating Gravity when Climbing

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

Restoring gravity when releasing a ladder

When the player moves left or right while on a ladder, or jumps, the character releases the ladder and gravity reasserts its ugly dominance. At the end of presence.climb, restore the gravity scale to normal:

until action
    character.gravityScale = 1
    return action()

What did we do?

We allowed the game to interpret up-down control input only when in contact with a ladder, by keeping track of when we come into contact with a ladder, and controlling the effect of gravity on the character while climbing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.113.188