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

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
3.15Mb size Format: txt, pdf, ePub
Using removeChild to completely get rid of objects

In all the game examples so far, you've removed objects from the game by setting their visible properties to false, like this:

_monster1.visible = false;

You can then check whether the object is still in the game or not with a simple if/else statement, like this:

if(_monster1.visible)
{
  //The monster is active, so keep
  //it moving and check for collisions
}
else
{
  //The monster isn't in the game anymore
}

This is an easy way of removing game objects, and it's often the best. The nice thing about this technique is that the objects still actually exist on the stage the entire time. If you have a game in which you hide and show the same objects over and over again, this is the way to do it. It's easy to reset games or game levels just by making objects visible again.

The only problem with this is that the game object still actually exists and is occupying memory space in the Flash Player. This could become a problem if you have hundreds of invisible objects on the stage that might still be running internal events, like timers or enterFrameHandlers. In that case, it's best to get rid of them completely with
removeChild
. Here's how:

removeChild(objectName);

If the object you want to remove is on the stage, remove it like this:

stage.removeChild(objectName);

If it's inside another class, like
LevelOne
, remove it like this:

this.removeChild(objectName);

To completely clear the object from memory, give any variables that refer to the object a null value, like this:

objectName = null;

What actually happens to the object when it's removed? AS3.0 has a
garbage collector
to do the job. You can think of the garbage collector as a little software robot that runs around your game looking for objects and properties that aren't being used or don't have any value and deletes them for good. This saves memory and processing power, and AS3.0 does this for you automatically. One of the jobs of the garbage collector is to find objects that have been removed with
removeChild
and wipe them from the Flash Player's memory. However, the garbage collector is a bit of a finicky fellow, so it's very picky about what it chooses to completely delete.

  • The garbage collector doesn't delete objects that have an
    ENTER_FRAME
    event running. These objects make the garbage collector a bit squeamish, so you have to manually remove the
    ENTER_FRAME
    event with
    removeListener
    , as you did in the
    removedFromStage
    event handlers. Although objects do remove their own event listeners (such as
    ADDED_TO_STAGE
    and
    REMOVED_FROM_STAGE
    ) it's considered good programming form to also remove them manually.
  • The garbage collector doesn't like
    MovieClip
    objects that are animated using a timeline. It doesn't touch them unless the animation is stopped by using the stop method.
  • If any objects have timers running using the
    Timer
    class, the garbage collector doesn't delete them.
  • The garbage collector doesn't delete an object if there are one or more variables in the game that make a reference to it.

Usually, however, AS3.0's garbage collector is pretty efficient about these sorts of things. As long as you keep these guidelines in mind, your game won't be unexpectedly slowed down by objects running in the background that you thought you deleted completely but hadn't.

If you've removed an object from a game with
removeChild
, you can test whether or not it exists by using an if statement that looks like this:

if(gameObject == null)
{
  //The object is no longer in the game
}

Remember also that when you remove an object from the stage, the object's
REMOVED_FROM_STAGE
event handler will be run, if you've created one for the object. That's a good place to remove timers or the object's
enterFrameHandler
to prevent them from secretly running in the background after the object has been removed.

Communicating between classes by dispatching events

The coolest bit of new programming voodoo you've used is the
dispatchEvent
method.

dispatchEvent(new Event("levelOneComplete", true));

This broadcasts an event called “levelOneComplete” to any other class that might be interested in listening for it. You can give this event any name you please, and you can dispatch as many events as you think your game will need.

Dispatching events is one of most useful things you can learn how to do as a game programmer. You've seen events used in almost every chapter in this book. Button clicks, timers, frames—almost every important thing in an AS3.0 program seems to happen because of an event. But so far, all the events that you've used have been built into AS3.0. By using the
dispatchEvent
method, you can create your own events and then trigger them whenever anything important happens in your game.

For example, imagine that you're making an adventure game in which the hero or heroine needs to steal a magical gingerbread cookie from a sleeping witch. As soon as the cookie has been stolen, it might be very
useful for other objects in the game to know that this has happened. You could inform the application class to update a score, you could inform the character to update its inventory, and you could even inform the sleeping witch who may well wake up if the player isn't tip-toeing quietly enough. Instead of informing each of these objects individually, however, the magical gingerbread cookie needs to broadcast only one event to the entire game: “I've been picked up!” This is known as
dispatching an event
. Other objects can then choose whether they want to listen to this event or take any action if it concerns them.

The elegance of this system is that the event isn't dispatched to a specific object, and the objects that are listening for the event don't need to know anything about the object that broadcast the event.

Here's a quick-start guide to dispatching events:

  1. Import the
    Event
    class.
    import flash.events.Event;
  2. When something happens that any objects in your game might be interested in, create an event for it using the
    dispatchEvent
    method. The basic format for creating an event looks like this:
    dispatchEvent(new Event("eventName", true));

    This directive broadcasts to the rest of your program that an event has occurred. You can give the event any name you like, such as
    "eventName"
    , as in this example.

  3. Any other class can now listen to this event by adding an event listener, like this:
    stage.addEventListener("eventName",eventNameHandler);

    In your games, you'll probably want to add the event listener to the stage for reasons I'll explain ahead. You can attach event listeners to any object, however.

  4. You then need to create the event handler to make something happen when the event occurs.
    private function eventNameHandler(event:Event)
    {
      trace(event.target);
    }

    In the event handler, you can use the event object's
    target
    property to access the object that called the event and all its properties. (If you want to access the object with which the event was registered, such as the stage in this example, use the currentTarget property.)

  5. Wait for the event to occur.

You can create events for anything in your game that you think other objects should know about, such as a door opening, an enemy being destroyed, or a variable changing its value. Any objects can then choose to listen to those events if they want to and take actions based on them.

By using events, objects can communicate with each other without having to depend on other classes to function properly. They can listen for events that interest them and change their own private properties internally.

Event bubbling

When events are dispatched, they travel through three different states:
capture
,
target
, and
bubbling
. The only one you're interested in is the
bubbling
state, which is most useful in the kinds of game design scenarios that you've seen at work in this book.

When an object dispatches an event, the object broadcasts the event like a radio station broadcasts a news item. Other objects can then “tune in” to the event if they want to listen to it.

Events aren't broadcast to every object in the program at the same time, however. They either travel up or down through the hierarchy of objects. You can listen to events at any point in this journey.

If an event is set to bubble, it means that the event travels up through the hierarchy. It starts with the child object and then informs the parent object. That parent object can then perform any action it needs to.
Figure 8-20
illustrates this.

Figure 8-20.
Events bubble up from the child to the parent object.

The
dispatchEvent
method has one argument, which is called the
event constructor
. It's highlighted here in bold:

dispatchEvent(
new Event("eventName", true)
);

The event constructor creates the event. Events can be made to bubble by setting the second argument in the event constructor to true:

new Event("eventName",
true
)

If you change it to false or leave it out entirely, the event doesn't bubble.

If other classes or objects want to listen to an event, they have to do it by attaching their event listeners to the parent object. Often, that object will be the stage, which is the common parent of all display objects. However, your games will be much easier to manage if you only have one class that's listening for events from all objects. That might be the application class or an intermediary class, like
LevelOne
in this chapter's example. That way the control of the game is centralized, and you'll know where in your code to look to change what your game objects should do if an event is triggered.

And that's really all you need to know about how to dispatch and listen for events in games.

Finishing off level one

You're just about finished with the first level of Monster Mayhem. The only class you haven't looked at is the
Background
class. All it does is display the background image'nothing special! Just for completeness, here's the entire
Background
class:

package
{
  import flash.display.DisplayObject;
  import flash.display.Sprite;
  public class Background extends Sprite
  {
    //Embed the image
    [Embed(source="../images/background.png")]
    private var BackgroundImage:Class;
    private var _background:DisplayObject
      = new BackgroundImage();
    public function Background()
    {
      this.addChild(_background);
    }
  }
}
Firing stars in four directions in level two

Level two introduces a few new twists to the game. There are now four monsters on the stage, and they move much faster. This was easy to implement by increasing their velocities from 1 pixel per frame to 2. Most of the rest of the code in
LevelTwo
is identical to
LevelOne
, but make sure that you take a look at all the code in its proper context in the
LevelTwo.as
file in the chapter's source files.

The biggest change in level two is that the game character can fire stars in all four directions, as illustrated in
Figure 8-21
.

Figure 8-21.
In level two, the character can fire stars in four directions.

Other books

A Proper Marriage by Doris Lessing
Blood & Lust: The Calling by Rain, Scarlett
Daughter's Keeper by Ayelet Waldman
Treachery in Death by J. D. Robb
The Things a Brother Knows by Dana Reinhardt
The Long Cosmos by Terry Pratchett
Unleashed by David Rosenfelt