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.
To manage scores, first we'll need to set it when a game begins.
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()
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()
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
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
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
To make the game interesting, the player should have a finite number of lives that determine when the game is over.
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()
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
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
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
.
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
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
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.
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
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
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
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
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
self.x, self.y = x, y end local lives = display.newGroup() self:insert(lives) lives.x, lives.y = 10, 7 return self
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
function lives:Lives(event) for i = 1, event.value do if self[i] then self[i].isVisible = true end end end
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
self.x = self.width * 1.1 * i end end for i = event.value + 1, self.numChildren do self[i].isVisible = false end end
18.119.111.9