Foundation Game Design with ActionScript 3.0, Second Edition (81 page)

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
9.26Mb size Format: txt, pdf, ePub

The monsters have a charming quality. When they're hit by the star, they open their mouths, as you can see in
Figure 8-9
.

Figure 8-9.
The monster opens its mouth when it's hit by a star. Poor thing!

The monster's mouth stays open for two seconds and then closes again.

You saw this in
Chapter 6
when you looked at how to change an object's image state when it collides with something. So you already know that this trick is done by making one image visible and the other invisible. What's new here is that the switching of images all happens
inside
the
Monster
class. The class uses a timer to keep the monster's mouth open for two seconds and then closes it again.

Here's the
Monster
class that makes this work:

package
{
  import flash.display.DisplayObject;
  import flash.display.Sprite;
  import flash.events.TimerEvent;
  import flash.utils.Timer;
  public class Monster extends Sprite
  {
     //Embed the monster images
    [Embed(source="../images/monsterMouthClosed.png")]
    private var MonsterMouthClosedImage:Class;
    [Embed(source="../images/monsterMouthOpen.png")]
    private var MonsterMouthOpenImage:Class;
    //Private properties
    private var _monsterMouthClosed:DisplayObject
      = new MonsterMouthClosedImage();
    private var _monsterMouthOpen:DisplayObject
      = new MonsterMouthOpenImage();
    private var _timer:Timer;
    //Public properties
    public var vx:int = 0;
    public var vy:int = 0;
    public var timesHit:int = 0;
    public function Monster()
    {
      this.addChild(_monsterMouthClosed);
      this.addChild(_monsterMouthOpen);
      _monsterMouthOpen.visible = false;
      //The mouth timer
      _timer = new Timer(2000);
    }
    //Public methods
    public function openMouth():void
    {
      _monsterMouthOpen.visible = true;
      _monsterMouthClosed.visible = false;
      _timer.addEventListener(TimerEvent.TIMER, mouthTimeHandler);
      _timer.start();
    }
    //Private methods
    private function mouthTimeHandler(event:TimerEvent):void
    {
      _monsterMouthOpen.visible = false;
      _monsterMouthClosed.visible = true;
      _timer.reset();
      _timer.removeEventListener
        (TimerEvent.TIMER, mouthTimeHandler);
    }
  }
}

The monsters have the same public properties as the character: vx, vy, and timesHit. But they also have a public method: openMouth.
Figure 8-10
illustrates this.

Figure 8-10.
The Monster class's public properties and methods

The
LevelOne
class can make a monster open its mouth at any time by calling the monster's
openMouth
method, like this:

_monster1.openMouth();
_monster2.openMouth();

The
Monster
class has a timer that is set to fire every two seconds (2000 milliseconds).

_timer = new Timer(2000);

When the monster's
openMouth
method is called, the image of it with an open mouth is made visible, and the image of it with a closed mouth is made invisible. The timer is then started.

public function openMouth():void
{
  _monsterMouthOpen.visible = true;
  _monsterMouthClosed.visible = false;
  _timer.addEventListener(TimerEvent.TIMER, mouthTimeHandler);
  _timer.start();
}

When the timer counts two seconds, it calls the
mouthTimeHandler
. This method makes the image of the monster with the closed mouth visible again and makes the open mouth image invisible. It then resets the timer so that it will start counting from zero the next time it's used. Finally, the timer's event listener is removed.

private function mouthTimeHandler(event:TimerEvent):void
{
  _monsterMouthOpen.visible = false;
  _monsterMouthClosed.visible = true;
  _timer.reset();
  _timer.removeEventListener
    (TimerEvent.TIMER, mouthTimeHandler);
}

What's important to notice is that the
Monster
class doesn't do anything that affects the logic of the game. All it does is handle the monster's change of state: it opens and closes its mouth. It's the
LevelOne
class that decides when this should happen based on what's happening in the game. It's important to design your game object classes like this so that you can reuse them in other games or levels without having to rewrite the class.

For example, maybe later you decide that the monster should also open its mouth when it bumps into a wall. You won't need to make any changes to the
Monster
class to do this. All you would need to do is write
_monster1.openMouth()
in the
LevelOne
class when the monster bumps into a wall.

Moving the monsters

Monster Mayhem is the first game you've seen where objects other than the game character move around the stage. The monsters randomly change their direction every second'either up, down, left, or right, as illustrated in
Figure 8-11
.

Figure 8-11.
The monster chooses a random direction every second.

The
levelOne
class uses a timer to trigger the
monsterTimerHandler
every second.

_monsterTimer = new Timer(1000);
_monsterTimer.addEventListener
(TimerEvent.TIMER, monsterTimerHandler);
_monsterTimer.start();

The
monsterTimerHandler
sends the
_monster1
and
_monster2
objects to the
changeMonsterDirection
method.

private function monsterTimerHandler(event:TimerEvent):void
{
  changeMonsterDirection(_monster1);
  changeMonsterDirection(_monster2);
}

The
changeMonsterDirection
method generates a random number between 1 and 4. It uses that random number to assign the monsters different vx and vy values, which will move the monsters either right, left, up, or down.

private function changeMonsterDirection(monster:Monster):void
{
  var randomNumber:int = Math.ceil(Math.random() * 4);
  if(randomNumber == 1)
  {
    //Right
    monster.vx = 1;
    monster.vy = 0;
  }
  else if (randomNumber == 2)
  {
    //Left
    monster.vx = -1;
    monster.vy = 0;
  }
  else if(randomNumber == 3)
  {
    //Up
    monster.vx = 0;
    monster.vy = -1;
  }
  else
  {
    //Down
    monster.vx = 0;
    monster.vy = 1;
  }
}

Figure 8-12 shows how this system works.

Figure 8-12.
The monsters are assigned a random direction.

The
enterFrameHandler
then uses these new vx and vy values to make the monsters move. It also uses the same
checkStageBoundaries
method used by the character to keep them within the playing field. However, all this code will only run if the monsters are visible.

if(_monster1.visible)
{
  _monster1.x += _monster1.vx;
  _monster1.y += _monster1.vy;
  checkStageBoundaries(_monster1);
}
if(_monster2.visible)
{
  _monster2.x += _monster2.vx;
  _monster2.y += _monster2.vy;
  checkStageBoundaries(_monster2);
}

In this game, the monsters have their visible properties set to false when they're hit by the star three times. Making them invisible is a simple way of removing them from the game. However, even if the monsters are invisible, they'll still be on the stage and can still be moved around by the
enterFrameHandler
. The if statement makes sure that the monsters aren't moved if they're invisible.

Programming the star weapon

When the player presses the space key, the star weapon becomes visible and is launched from the center of the character. It spins and moves up the stage. If it hits the playing field border or a monster, it becomes invisible again. The first two times it hits a monster, the monster opens its mouth, but on the third time an explosion graphic is displayed and the monster disappears.
Figure 8-13
illustrates how the star weapon works.

Figure 8-13.
Fire the star weapon to vanquish the monsters.

The
Star
class shares the same vx and vy properties as the other game objects, but includes a new one called launched. This is a Boolean variable that tells the game whether or not the player has launched the star by pressing the space key. You'll see how important this property will become in controlling the behavior of the star. Here's the entire Star class:

package
{
  import flash.display.DisplayObject;
  import flash.display.Sprite;
  public class Star extends Sprite
  {
    //Embed the image
    [Embed(source="../images/star.png")]
    private var StarImage:Class;
    //Private properties
    private var _star:DisplayObject = new StarImage();
    //Public properties
    public var vx:int = 0;
    public var vy:int = 3;
    public var launched:Boolean = false;
    public function Star()
    {
      this.addChild(_star);
      //Center the star image
      _star.x = -(_star.width / 2);
      _star.y = -(_star.height / 2);
    }
  }
}

Other books

Stirring Attraction by Sara Jane Stone
I, Spy? by Kate Johnson
Vampire Breed by Tim O'Rourke
Honest illusions(BookZZ.org) by [Roberts Nora] Roberts, Nora
Head of the River by Pip Harry
Never Ending by Kailin Gow
Brighton Rock by Graham Greene
Distant Echoes by Colleen Coble
Wedding Cake Wishes by Dana Corbit