Adding finishing touches

Although the game is functionally working at this point, it's not really ready for the prime time. The way the bats just fade out and keep flying could easily confuse players. The high scores table could use a little more excitement. Finally, since we're reusing Creative Commons art assets, some credit information is in order.

Getting ready

Copy the explosion.lua file from the version 5 subfolder of the project pack into your project directory. This file provides the sprite sheet info and a simple function to create and animate a small explosion at a given point.

Getting on with it

First, we're going to make the bat's death a little more dramatic, adding a little explosion and causing the bat to fall off the bottom of the screen instead of continuing to fly. Open up the bat.lua file and find the mobDied local function, which is registered to go off in response to the creature's Death event, and delete the line that says self.alpha = 0.3:

local function mobDied(self, event)
  transition.cancel(self.Flight)

The first thing we're going to do is stop the bat's normal flight course:

  transition.cancel(self.Flight)
  explosion(self.parent, self.x, self.y)

We'll use the new explosion module to create an animated explosion in the bat's world environment at its current point. The explosion is responsible for animating itself and deleting itself when the animation is done.

Changing the creatures' motion

We want the bat to seem to fall when it is killed:

  explosion(self.parent, self.x, self.y)
  transition.to(self, {time = 1000, x = display.contentWidth})

We'll start the bat sliding sideways off the right-hand side. Because we're looking for a natural bouncing motion under the effects of gravity, the horizontal aspect of the motion will be tweened linearly, while the vertical component will be tweened quadratically; this means we need two separate transitions:

  transition.to(self, {time = 1000, x = display.contentWidth})
  local distance = 100 + (display.contentHeight - self.y)

We calculate the total distance the bat will travel vertically to rise up 50 pixels and then fall off the bottom of the screen. We add 100 because it will also fall the extra 50 pixels that it bounced up:

  local distance = 100 + (display.contentHeight - self.y)
  transition.to(self, 
    {
      time = 1005, transition = arc, onComplete = clean;
      y = display.contentHeight
    }
  )

Animating on a custom curve

Because the bat will first bounce up a little, then fall, its vertical motion will be determined by a custom tweening function, arc, which we will write in a moment. This transition is made slightly longer than the first one, because it will clean up the object (and post a remove event) when it's done, and we want to make sure the other transition has finished first:

local function arc(t, tMax, start, delta)
  if t <= 250 then
    return easing.outQuad(t, 250, start, -50)
  else
    return easing.inQuad(t - 250, tMax - 250, start - 50, delta + 50)
  end
end

local function mobDied(self, event)

This is our custom tweening function. It isn't terribly fancy; it transitions the object back, against the direction of the tween, for the first 250 milliseconds, then tweens it forward from that point for the rest. It relies on Corona's existing quadratic tweens (a decelerating tween for the upward motion, and an accelerating one for the fall) to calculate the intervening values.

Adding visual interest to the high scores

Now the bat dies a little more dramatically and we can move on to animating the credits and high scores. Close bat.lua and open menu.lua, and add a new text object to the scene:createScene function:

  self.ScoresWindow.x, self.ScoresWindow.y = 40, 190

  local creditsText = [[
Bat Swat code:
  Nevin Flanagan
Images:
  Bat Sprite:
    MoikMellah
  Environment art:
    Jetrel
  Licensed from
  opengameart.org
  under CC-By 2.0]]
  self.Credits = display.newText(self.ScoresWindow, creditsText, -16, 0, 190, 144, native.systemFont, 12)
end

This credits object will trade places periodically with the high-scores display, so whenever it fades out, it needs to cue the high-score object to slide into the empty space:

  self.Credits = display.newText(self.ScoresWindow, creditsText, -16, 0, 190, 144, native.systemFont, 12)
  self.Credits:addEventListener('Faded', function() self.StopEffects = visuals.SlideInFadeOut(self.ScoresSlide) end)
end

We don't want the credits to appear until the high scores have faded out, so make them completely transparent whenever the scene starts:

function scene:enterScene( event )
  self.Banner.alpha = 0
  self.Credits.alpha = 0

  if event.params and event.params.Score then

This means that in order for it to ever appear, it needs to be cued in whenever the high scores fade out, which we'll set up in the revealScores function:

    score.x = 100
  end
  scene.ScoresSlide:addEventListener('Faded', function (...) scene.StopEffects = visuals.SlideInFadeOut(scene.Credits) end)
end

In order for the object to ever receive a Faded event, we'll have to start the same transition on it:

  scene.ScoresSlide:addEventListener('Faded', function (...) scene.StopEffects = visuals.SlideInFadeOut(scene.Credits) end)
  return visuals.SlideInFadeOut(scene.ScoresSlide)
end

This moves the collected scores down off the screen, and schedules them to slide back in after a second and a half. Returning the resulting cancellation function means that the Cycle function will store it in the scene.StopEffects field. This is important, because if we start a game, we need to be able to cancel that transition. We can do that from the scene:exitScene function.

function scene:exitScene( event )
  self.StopPulsing()
  if self.StopEffects then
    self.StopEffects()
  end
end

Parameterizing the game length

Finally, we need to update the number of bats per scene; right now, it is set to a test value of 5. The document specifies 30 per game. To leave ourselves room for flexibility in the future, we'll have the menu pass in the desired number when it calls the game scene, much the same way the game passes the final score out. Go to the top of menu.lua and add the following line:

local scene = storyboard.newScene()

local options = {params = {Count = 30}}

function scene:tap(event)

We'll reuse this table as we relaunch the game scene. Now, we just need to supply it when we launch the game, which is in the function right under that:

local options = {params = {Count = 30}}

function scene:tap(event)
  storyboard.gotoScene("game", options)
  return true

Adding a reference to the options table tells storyboard to pass the parameters in to the scene being opened. Finally, we can save and close menu.lua, open game.lua, and make one change to the scene:enterScene function:

function scene:enterScene( event )
  self.ScoreTotal = 0
  self:dispatchEvent{name = 'Score'; total = self.ScoreTotal}
  self.StartingCount = event.params.Count
  self.Count = self.StartingCount

Instead of setting the game's starting creature count to a fixed 5, we'll set it to whatever is passed in by the menu.

What did we do?

Now, we added additional animations to the dying bats by modifying only one function (and adding another one for it to call). We also added a little animation to create visual interest and made control of the game scene more flexible.

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

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