Interacting with objects

The game would be singularly uninteresting if all you could do is walk around the levels and look at them.

Getting on with it

Open world.lua, if needed, and find the function self:Add. Our first step here will be to register the world to detect taps on those objects that the player can manipulate.

Registering interactive objects with the world

Check whether the new object has an Interact function. If it does, add the world as a tap listener on the new object:

      self:Place(actor, x, y)
      if object.Interact then
        actor:addEventListener('tap', self)
      end
      return actor

Next, add a tap handler to the world object:

    alignBackground(self, self.Ground)
  end
  function self:tap(event) 
  end
  function self:Add(object, x, y)

Because the player character represents the player in the game world, a game object can only be interacted with if the player character is next to it. The first step to determine this is to identify the tile the object is on from the event coordinates:

  function self:tap(event)
    local x, y = self:contentToLocal(event.x, event.y)
    x, y = math.ceil(x / self.HSize), math.ceil(y / self.VSize)
  end

Next, the nearby squares are checked for the presence of at least one character (we'll write this function momentarily):

    x, y = math.ceil(x / self.HSize), math.ceil(y / self.VSize)
    local character = seekAdjacentCharacer(self.Map, x, y)
    if character then
    end
  end

The object being interacted with is passed the specific character who is using it, in case it has some special effect on them:

    if character then
      event.target.Info:Interact(character)
    end

At the top level of the file, add the function to scan adjacent squares for a character:

  ground.x, ground.y = x * world.HSize, y * world.VSize
end

local function seekAdjacentCharacter(map, x, y)
end

return function (terrain, columns, rows)

This function will test adjacent offsets from the space where the object is located, starting with the space above it, until it reaches that space again:

local function seekAdjacentCharacter(map, x, y)
  local dX, dY = 0, -1
  repeat
  until dY == -1
end

To advance between clockwise adjacent spaces, the loop will use a programmers' trick to swap the x and y offsets, negating the y offset to ensure that it covers all four spaces:

  repeat
    dX, dY = -dY, dX
  until dY == -1

In each space, the function will look through the local features and see if any of them is a character. If so, its work is done and it returns what it has found.

  repeat
    local row = self.Map[y + dY]
    local space = row and row[x + dX]
    if space then
      for _, feature in pairs(space.Features) do
        if feature.Character then
          return feature
        end
      end
    end
    dX, dY = -dY, dX
  until dY == -1

Adding interactivity to an object definition

Finally, we need to add a description, wherever appropriate, to objects that are interactive, so that the world knows to monitor them. The common set contains only one interactive object, the chest. Add the Interact function to the common.chest definition in objects/common.lua:

common.chest = object {
  Embody = function(self)
    return display.newSprite(sheet, sequences.chest)
  end;
  EnterSpace = false;
  Interact = function (self, player)
  end;
}

This function will be responsible for using a function on the interacting player to give them a mark of progress toward their goal, a new item in their inventory (distinct from an item in the world):

  Interact = function (self, player)
    if not self.Opened then
      self:setSequence("open")
      player:Give("coin")
      self.Opened = true
    end
  end;

What did we do?

We added conditional touch registration, so that the system will only spend time processing those objects that do something when touched.

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

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