Recognizing kills and recording scores

The world-level interactions between the player, asteroids, and lasers are effectively complete at this point. The remaining tasks are for the game to track those elements that are not part of the world representation; accomplishments and challenges.

Getting on with it

To manage scores, first we'll need to set it when a game begins.

  1. Open game.lua and find the enterScene handler, set the starting value for player score, and dispatch a game event:
      Runtime:addEventListener('touch', self)
      self.Score = 0
      self:dispatchEvent{name = 'Score'; value = self.Score}
      self:Start()
  2. To trigger changes in the score, the game needs to track Destroy events for rocks, which it can receive from the world:
      self:dispatchEvent{name = 'Score'; value = self.Score}
      self.World:addEventListener('Destroy', self)
      self:Start()
  3. Before moving on, keep registration balanced by removing the listener in the exitScene handler:
    function scene:exitScene( event )
      Runtime:removeEventListener('Tilt', self)
      Runtime:removeEventListener('Shake', self)
      Runtime:removeEventListener('touch', self)
      self.World:removeEventListener('Destroy', self)
      self:Stop()
    end
  4. Next, add another condition to the check in the game scene's Destroy handler, since this function will handle events from both sources:
        self:addEventListener('clock', reset)
      elseif event.kind == 'rock' then
        local rock = event[1]
      end
    end
  5. When a rock is destroyed, adjust the score and broadcast an event with the new score:
      elseif event.kind == 'rock' then
        local rock = event[1]
        self.Score = self.Score + rock.Points
        self:dispatchEvent{name = 'Score'; delta = rock.Points, value = self.Score}
      end

Tracking lives

To make the game interesting, the player should have a finite number of lives that determine when the game is over.

  1. Start by going back to the enterScene handler and setting the initial lives counts along with the starting score:
      self.World:addEventListener('Destroy', self)
      self.Lives = 2
      self:dispatchEvent{name = 'Lives'; value = self.Lives}
      self:Start()
  2. Return to the Destroy event handler, and modify the branch for the player to adjust the number of lives and broadcast the change in an event:
        self:addEventListener('clock', reset)
        self.Lives = self.Lives - 1
        self:dispatchEvent{name = 'Lives'; delta = -1, value = self.Lives}
      elseif event.kind == 'rock' then
  3. If no lives remain available when the player is destroyed, the game is over; announce this to the game object with a Game state event:
      if event.kind == 'ship' then
        if self.Lives <= 0 then
          timer.performWithDelay(1, 
            function(...)
              self:dispatchEvent{name = 'Game'; action = 'stop', Score = self.Score}
            end
          )
        else
          local player = event[1]
          local function reset(event)
            self:removeEventListener('clock', reset)
            player.x, player.y = player.parent:contentToLocal(display.contentCenterX, display.contentCenterY)
            player:setLinearVelocity(0, 0)
          end
          self:addEventListener('clock', reset)
          self.Lives = self.Lives - 1
          self:dispatchEvent{name = 'Lives'; delta = -1, value = self.Lives}
        end
      elseif event.kind == 'rock' then
  4. In response to that event, the game should pause the simulation and return to the menu screen:
    scene:addEventListener('Game', scene)
    function scene:Game(event)
      physics.pause()
      storyboard.gotoScene('splash')
    end
    
    local threshold = 1 / 6
    
    function scene:Tilt(event)

    Now that this event is being fired, there's one last piece of clean-up we can do properly. Save game.lua and open player.lua.

  5. Before the constructor function returns the new object, register it to receive Game events from the game and respond to them:
      function self:Destroy(event)
        explosion(self.parent, self.x, self.y)
      end
      input:addEventListener('Game', self)
      function self:Game(event)
      end
      return self
  6. In that handler, clean up the events that the player has registered for on the game object, since the player object is about to be disposed of.
      function self:Game(event)
        if event.action == 'stop' then
          world:removeEventListener('clock', self)
          input:removeEventListener('Thrust', self)
          input:removeEventListener('Yaw', self)
          input:removeEventListener('Fire', self)
          input:removeEventListener('Jump', self)
          input:removeEventListener('Game', self)
        end
      end

Displaying lives and the score

The last element to managing game progress is to make it visible to the player; no game will hold a player's interest if they can't see themselves getting closer to their goal. For this, we'll use a new group to hold the display elements, which we'll create along with the world.

  1. All the appropriate events are already in place, so load and call the new module in createScene of game.lua, and install the resulting group in the scene:
      self.World = require "world" (self)
      group:insert(self.World)
      self.UI = require "interface" (self)
      group:insert(self.UI)
    end
  2. Next, create the interface.lua module file. Open it and frame in the function to create the new layer:
    return function(game)
      local self = display.newGroup()
      return self
    end
    
  3. Add a text object to the layer to display the score:
      local self = display.newGroup()
      local score = display.newText(self, "", 10, 7, native.systemFont, 14)
      score:setReferencePoint(display.TopRightReferencePoint)
      score.x, score.y = display.contentWidth - 10, 7
      return self
  4. Register this text as a listener for Score events on the game, and give it a handler to process them:
      score.x, score.y = display.contentWidth - 10, 7
      game:addEventListener('Score', score)
      function score:Score(event)
      end
      return self
  5. This handler can just display the new value in the text object, realigning the text as needed:
      function score:Score(event)
        local x, y = self.x, self.y
        self.text = tostring(math.floor(event.value))
        self:setReferencePoint(display.TopRightReferencePoint)
        self.x, self.y = x, y
      end
  6. To keep the lives display contained, create a new group and make it a child of this one. Position it a little in from the top-left corner. This group will hold one child image visible for each life the player has:
        self.x, self.y = x, y
      end
      local lives = display.newGroup()
      self:insert(lives)
      lives.x, lives.y = 10, 7
      return self
  7. Register this group to receive Lives events from the game and handle them:
      lives.x, lives.y = 10, 7
      game:addEventListener('Lives', lives)
      function lives:Lives(event)
      end
      return self
  8. When an event is received, the group first shows as many children as the player has lives:
      function lives:Lives(event)
        for i = 1, event.value do
          if self[i] then
            self[i].isVisible = true
          end
        end
      end
  9. If not enough images are available, it creates them:
        for i = 1, event.value do
          if self[i] then
            self[i].isVisible = true
          else
            local new = display.newImage(self, "image/life.png")
            new:setReferencePoint(display.TopRightReferencePoint)
            new.x, new.y = new.width * 1.1 * I, 0
          end
        end
  10. Finally, it hides any life images already created that aren't required right now:
            self.x = self.width * 1.1 * i
          end
        end
        for i = event.value + 1, self.numChildren do
          self[i].isVisible = false
        end
      end

What did we do?

We leveraged existing events to manipulate game-specific progress values, the player's accumulated score, and remaining lives. We created events to track those values, and a visible UI layer to display the values of those events.

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

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