Read Foundation Game Design with ActionScript 3.0, Second Edition Online
Authors: Rex van der Spuy
Here's howcheckGameOver
works:
_levelWinner
.if(_monster1.timesHit == 3
&& _monster2.timesHit == 3)
{
_levelWinner = "character"
//...
}
if(_character.timesHit == 1)
{
_levelWinner = "monsters"
//...
}
enterFrameHandler
, which freezes all the action on the stage. If the character has lost, the code sets the character'salpha
to 0.5, which makes it semitransparent.this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
_character.alpha = 0.5;
TIMER
event handler so that you stop assigning random directions to the monsters. It's important do this because the monster timer won't quit automatically when the level is finished. You don't want to waste precious CPU power running the timer if you don't need to._monsterTimer.removeEventListener(TimerEvent.TIMER, monsterTimerHandler);
_gameOverTimer
, which callsgameOverTimerHandler
._gameOverTimer = new Timer(2000);
_gameOverTimer.addEventListener
(TimerEvent.TIMER, gameOverTimerHandler);
_gameOverTimer.start();
It's thegameOverTimerHandler
that does the work of displaying the “Level Complete” message or “Game Over” message and informing the application class that the level has been finished. Let's see how this works next.
ThegameOverTimerHandler
introduces some new techniques.
Here's thegameOverTimerHandler
that does this, and I'll explain how it works in detail next.
private function gameOverTimerHandler(event:TimerEvent):void
{
if(_levelWinner == "character")
{
if(_gameOverTimer.currentCount == 1)
{
_gameOver.levelComplete.visible = true;
}
if(_gameOverTimer.currentCount == 2)
{
_gameOverTimer.reset();
_gameOverTimer.removeEventListener
(TimerEvent.TIMER, gameOverTimerHandler);
dispatchEvent(new Event("levelOneComplete", true));
}
}
if(_levelWinner == "monsters")
{
_gameOver.youLost.visible = true;
_gameOverTimer.removeEventListener
(TimerEvent.TIMER, gameOverTimerHandler);
}
}
Let's first take a look at what happens when the monsters win the game because the code is very simple. The_gameOverTimer
removes thegameOverTimerHandler
so that all this code isn't called a second time.
_gameOverTimer.removeEventListener(TimerEvent.TIMER, gameOverTimerHandler);
The code also makes_gameOver
object'syouLost
subobject visible.
_gameOver.youLost.visible = true;
The_gameOver
object was added to the game by theLevelOne
class when the class was initialized.
private var _gameOver:GameOver;
//...
addGameObjectToLevel(_gameOver, 140, 130);
It's been sitting on the stage the whole time, but you couldn't see it because the subobjects that it contains have been invisible. TheGameOver
class contains two subobjects:youLost
andlevelComplete
. Their visible properties are both set to false when they're added to their parent class. Here's the completeGameOver
class that does this:
package
{
import flash.display.DisplayObject;
import flash.display.Sprite;
public class GameOver extends Sprite
{
//Embed the images
[Embed(source="../images/levelComplete.png")]
private var LevelCompleteImage:Class;
[Embed(source="../images/youLost.png")]
private var YouLostImage:Class;
//Private properties
public var levelComplete:DisplayObject
= new LevelCompleteImage();
public var youLost:DisplayObject = new YouLostImage();
public function GameOver()
{
//Add the images to this class
//and make them invisible
this.addChild(levelComplete);
levelComplete.visible = false;
this.addChild(youLost);
youLost.visible = false;
}
}
}
Figure 8-17 shows the effect that making the_gameOver
object'syouLost
subobject visible has when the monsters win the game.
Figure 8-17.
Making the “You lost” message visible
So, if the monsters win, that's the end of the game and nothing else happens. Things get a lot more interesting if the character wins.
When the_gameOverTimer
is created, it's initialized so that it calls thegameOverTimerHandler
every two seconds.
_gameOverTimer = new Timer(
2000
);
_gameOverTimer.addEventListener
(TimerEvent.TIMER,
gameOverTimerHandler
);
_gameOverTimer.start();
As mentioned in
Chapter 7
, timers have a property called currentCount that counts the number of times the timer has run. In this example, the_gameOverTimer
will increase its currentCount property by 1 every two seconds. The game uses this feature to manage displaying the “Level Complete” message and to load level two.
Then currentCount starts counting from 0 and the timer fires once every 2,000 milliseconds. That means that when it becomes 1, two seconds have already passed. When currentCount becomes 2, four seconds have passed. Here's how it's used to manage the transition from level one to level two:
enterFrameHandler
is removed by thecheckGameOver
method. ThecheckGameOver
method also starts the_gameOverTimer
._gameOverTimer
is also reset.)Figure 8-18 illustrates how the_gameOverTimer.currentCount
property is managing the last four seconds of the game.
Figure 8-18
. The timer is used to end level one and transition to level two.
Here's the code in thegameOverTimerHandler
method that actually does this:
if(_levelWinner == "character")
{
if(_gameOverTimer.currentCount == 1)
{
_gameOver.levelComplete.visible = true;
}
if(_gameOverTimer.currentCount == 2)
{
_gameOverTimer.reset();
_gameOverTimer.removeEventListener
(TimerEvent.TIMER, gameOverTimerHandler);
dispatchEvent(new Event("levelOneComplete", true));
}
}
You should now understand what this code is doing, except for this one very important line:
dispatchEvent(new Event("levelOneComplete", true));
This bit of code is
dispatching an event
calledlevelOneComplete
. It's broadcasting this message to the rest of the game that level one is finished. Any objects who are interested in this message can listen for it and perform some kind of action when they hear this event being broadcast.
TheMonsterMayhem
application class is extremely interested in this event because it needs to know when level one is finished. Let's take a look at theMonsterMayhem
class again. I've highlighted all the code that adds a listener for thelevelOneComplete
event and theswitchLevelHandler
that takes some action when it hears it.
package
{
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="550", height="400",
backgroundColor="#FFFFFF", frameRate="60")]
public class MonsterMayhem extends Sprite
{
private var _levelOne:LevelOne;
private var _levelTwo:LevelTwo;
public function MonsterMayhem()
{
_levelOne = new LevelOne(stage);
_levelTwo = new LevelTwo(stage);
stage.addChild(_levelOne);
stage.addEventListener
("levelOneComplete", switchLevelHandler);
}
private function switchLevelHandler(event:Event):void
{
trace("Hello from the application class! Switch levels!");
stage.removeChild(_levelOne);
_levelOne = null;
stage.addChild(_levelTwo);
}
}
}
TheMonsterMayhem
application class listens for thelevelOneComplete
event by attaching an event listener to the stage.
stage.addEventListener("levelOneComplete", switchLevelHandler);
The listener waits until this line of code is run by any object on the stage:
dispatchEvent(new Event("levelOneComplete", true));
As soon as it hears this event, the application class runs itsswitchLevelHandler
.
private function switchLevelHandler(event:Event):void
{
trace("Hello from the application class! Switch levels!");
stage.removeChild(_levelOne);
_levelOne = null;
stage.addChild(_levelTwo);
}
TheswitchLevelHandler
does these things:
trace("Hello from the application class! Switch levels!");
removeChild
method to remove the_levelOne
object from the stage. It also gives the_levelOne
object a value of null, which clears it from the Flash Player's memory.stage.removeChild(_levelOne);
_levelOne = null;
_levelTwo
object to the stage.stage.addChild(_levelTwo);
Figure 8-19 shows how theMonsterMayhem
application class can “hear” when_levelOne
dispatches an event.
Figure 8-19.
Using events to switch levels
This is the first time you've seen howremoveChild
is used, and it's also the first time you've seen how a class can listen for an event being broadcast by another class. Let's take a slightly deeper look at these two new features.