Part 3 : Initializing The Game

So now that we have the main loop taken care of, let’s start building an actual, functional game. For this lesson, we are going to do the following:

  1. Display a TitleScreen
  2. Initialize a new game
  3. Put the player on the screen
  4. Capture movement for the player and fire missiles
  5. Allow the game to be paused

First, we will add some code to set depths for the object on the screen. Setting depths has been the bane of existence for Flash game developers for many years. We will try to make it as easy as possible for this game. By the way, AS3 adds the addChild(), which makes the old way of managing depths unnecessary. However, this opens up its own new set of difficulties.

static var PLAYER_DEPTH 		= 1000;
static var MISSILE_MIN_DEPTH 	= 2000;
static var MISSILE_MAX_DEPTH 	= 3000;
static var TITLE_SCREEN_DEPTH 	= 10000;
static var END_SCREEN_DEPTH	= 10010;

The variables above were created as “static” so that, if need be, we could discover their values from an outside class without having to create an instance of “HomeWars”. In reality, we will probably never need to get these static values from outside this class, but this is an example of what to do if that was a requirement for your game.

Next, we need to set-up the constructor for our class. The class constructor is always a function that is named the same thing as the class. It gets called automatically when a class is instantiated. Instantiating a class simply means creating an object or instance of that class type that you can use in your code. A class instance has a set of it’s own poperties (variables) and methods (functions) that operate independently of other objects.

Here is our constructor code:

function HomeWars(pt) {
	EventDispatcher.initialize(this);
	parentTL = pt;
	gameState =	STATE_TITLE_SCREEN ;
}
EventDispatcher.initialize(this);

This line of code sets up the class to use the Flash Event model for creating custom events. We will be using this model to communicate among the various objects in the game.

parentTL = pt;

We need a Flash timeline on which to attach all of our objects. We will be using the root timeline for this game, but this could be any MovieClip that is set to location 0,0 on the screen.

Notice that we set the gameState to “STATE_TITLE_SCREEN“. This will make our switch() statement in the run() function move the game into that “state” the next time it fired from onEnterFrame. Now we will look at the the functions for showing the title screen. This only important for our discussion because it shows how to handle very basic custom events in Flash. The three functions necessary to show the title screen are below:

function fSTATE_TITLE_SCREEN() {
		titleScreen = parentTL.attachMovie("FTitleScreen","titlescreen", TITLE_SCREEN_DEPTH);
		titleScreen.setLocation(0,0);
		titleScreen.addEventListener("EventCloseTitleScreen", this);
		gameState = STATE_WAIT_FOR_CLOSE;
	}

This function attaches the FTitleScreen object from the library, displaying it at the depth specified in TITLE_SCREEN_DEPTH, and place it at 0,0 on the screen. It then adds the HomeWars object instance as a “listener” for the event “EventCloseTitleScreen”. Here is what the titlescreen will look like when it is shown:

part 3 the title screen

(Note: See that weird looking type-writer looking thing at the bottom of the screen? That’s an Atari 800, the greatest 8-bit home computer ever made. Don’t ask for evidence, just believe)

Finally, it set’s the game state to go into “wait” mode. This is an empty function that will be called until the user closes the TitleScreen to play the game.

function EventCloseTitleScreen(e:Object) {
		titleScreen.removeMovieClip();
		gameState = STATE_INIT;

	}

The function above is the event that will be called from the instance of TitleScreen when the “Play” button is pressed. Notice that the name of the function is the same as the name of the event. I like to prefix all my Event callback function names with “Event” just for self-documentation purposes, but they do not have to be named that. However, they do need to be named the same thing as the Event specified in the addEventListener function.

function fSTATE_WAIT_FOR_CLOSE() {
		//waiting
	}

As stated before, the function above does nothing. It’s just a wait state. We can reuse this function whenever our state is to simply wait for user interaction. Now we must create the TitleScreen.as file that will work with our FTitleScreen object in the library. By using attachMovie()with a MovieClip associated with a class in the library, you will create an instance of that MovieClip that has all the properties and functions of the class. By right-clicking on aMovieClip in the library you can set the associated class for a MovieClip:

Part 3 linkage properties

Here is what the full code looks like:

import mx.events.EventDispatcher;
import mx.utils.Delegate;
class TitleScreen extends MovieClip { 

        var play_button:MovieClip; 

        function TitleScreen() {
                EventDispatcher.initialize(this);
                play_button.onRelease = Delegate.create(this,EventClickPlayButton);
        }       

        public function setLocation(x:Number,y:Number) {
                this._x = x;
                this._y = y;
        } 

        function EventClickPlayButton() {
                this.dispatchEvent({type:"EventCloseTitleScreen"});
        } 

        public function addEventListener(){/*Interface Stub*/}
        public function removeEventListener(){/*Interface Stub*/}
        public function dispatchEvent(){/*Interface Stub*/}
}

The most interesting parts of this class are described below.

play_button.onRelease = Delegate.create(this,EventClickPlayButton);

This line of code in the constructor sets the [PLAY] button to call EventClickPlayButton when the user clicks it. This is commonly known as a callback function. The Delegate.create() static function call is used to assign the context of the TitleScreen object to play_button when it is pressed. If we did not do this, the EventClickPlayButton() function would be called as if it was part of the play_button object, and it would not have access to our instance of TitleScreen without using _parent. This is a messy practice, and can sometimes get you into variable scope issues. By the way, this has been fixed in AS3, and you will not need to use Delegate() to access the context of the class that has assigned a callback function to an object.

function EventClickPlayButton() {
                this.dispatchEvent({type:"EventCloseTitleScreen"});
        }

This function dispatches the EventCloseTitleScreen event to all the objects listening for it. In this case, our instance of the HomeWars class is a listener. The parameter passed in the calls to dispatchEvent is an object, and it can contain multiple parameters. The Type parameter is mandatory, because it describes the event that is being dispatched. We will be using this basic event model throughout the construction of the game, and I will avoid describing it again. Just remember, one object must subscribe to an event using the addEventListener() function of said object, and any object that wants to broadcast that event to all subscribers must use dispatchEvent.

Recall that after this Event is broadcast, the function EventCloseTitleScreen() in our instance of HomeWars will be called.

function EventCloseTitleScreen(e:Object) {
		titleScreen.removeMovieClip();
		gameState = STATE_INIT;

	}

This function deletes the TitleScreen object, and sets the gameState to initialize the game. The switch() statement in our run() function will now bet set to call this function.

function fSTATE_INIT() {
		player = parentTL.attachMovie("FPlayer", "player1",  PLAYER_DEPTH);
		player.setLocation((Stage.width/2)-(player._width/2),Stage.height-player._height);
		this.addEventListener("Move",player);
		this.addEventListener("Render",player);
		gameState = STATE_PLAY;
	}

We will initialize the game by placing our player in the screen, (the first two line) and set-up the events necessary for it to interact with HomeWars (the second 2 lines). Placing the player on the screen is done in the same way we placed the TitleScreen object on the screen.

this.addEventListener("Move",player);
this.addEventListener("Render",player);

All of the on-screen objects will listen to these two events: Move and Render. Move will calculate the next position of the object and Render will actually place it in it’s new position. This structure is not really necessary for the game we will be making, but for anything more complex it would be essential. The theory behind it is this: You calculate the Next position of your objects, test collisions on those calculations, then Render all the objects to the screen. This is done to prevent objects from passing through each other if their speeds are such that they would jump too many pixels to register a “hit” if all were moved at once. While this game is too simple to deem this necessary, a “Breakout” style game, for example, would require it so that the ball would not pass through bricks or walls unexpectedly.

Read the rest of the series: ‘Anatomy of a Flash Game’

  1. Anatomy of a Flash Game: Lesson 1 – Setting up the game
  2. Anatomy of a Flash Game: Lesson 2 – Creating Enemies & The Game Environment
  3. Anatomy of a Flash Game: Lesson 3 – MochiAds, MochiBot and MochiAds Leaderboards