I never thought development of web games can be that simple until I started development of my first game with Adobe Flex. I made two games, without any prior experience with Action script, in only ten months: "Fitter" and "RGB".

I found many answers to my questions on different forums and web sites, and it is time to share my knowledge with Flex community.

Monday, January 11, 2010

Thinking ahead

If you are reading this tutorial, you most probably wish to learn how to create games with Flex. The reason why we were working on the game menu so far, is because it is easier to learn the basics on simple things. Eventually, we will start development of the game itself, that is why we have to be prepared. We need to somehow separate game menu functionality from the functionality of the game. First we will implement state automaton and then break SnakesAdventure.as into three files.

State automaton

State automaton or state machine is a model composed of a number of states. At the moment our program has only one state, we will simply name it game menu. Let's pretend that we already implemented first stage of the game. When the player chooses new game option, new state becomes active. We will call this state game.

Why is this important? Let me give you an example. In previous chapter we implemented mouse handler which will be active in both states. In game menu, functions MouseDown/Up/Move control the behaviour of game options when mouse cursor is positioned over or away from label area. When the program will be in the game state, tasks of all three functions will be completely different. That is why we need to know the state of program at the moment the event occurs and execute the right code.

For state management we need only one variable, initialized with the value of the state at the start of the program. Each state will be defined with one constant value. Put the following definitions to other definitions in SnakesAdventure.as:

private static const GAME_MENU:int = 1;
private static const GAME:int = 2;

private var state:int = GAME_MENU;

Breaking the code

At the moment source code of the project is split in two files: Images.as and SnakesAdventure.as. Images.as contains only few definitions of embedded images. On the other hand, SnakesAdventure.as is growing with each chapter - my version already is almost 150 lines long. This should not be a problem for now, but in the future file size will grow with each new implemented feature and source code in the file will soon become a mess. From my experience, it is better to keep the source code clean from the beginning.

That is why we will now split content of SnakesAdventure.as into three files: SnakesAdventure.as, GameMenu.as and Game.as. I suggest you download my version of the project and briefly review all three files. I will try to explain what and why has been changed.

First I made two empty files: GameMenu.as and Game.as. Then I added include statements for both files into SnakesAdventure.as (line 7 and 8). From now on both files are included in compilation process.

I moved the code, specific to game menu from SnakesAdventure.as, into GameMenu.as:
- definitions of OPTION_ constants
- definition of variables pressedOption, titleScreenBitmap, gameOptionsBitmap and gameOptionBackgroundBitmap
- Draw_TitleScreen function
- Draw_GameOptions function

Then I moved the content of Draw function (SnakesAdventure.as) into new function Draw_GameMenu in GameMenu.as. I did the same with MouseDown/Up/Moved, new functions in GameMenu.as now have names MouseDown_GameMenu, MouseUp_GameMenu and MouseMoved_GameMenu.

We don't have any code as far as game is concerned, that is why file Game.as is very short. Only four functions with empty bodies are inside this file: Draw_Game, MouseDown_Game, MouseUp_Game, MouseMoved_Game. This functions will be executed when events occur while the program is in the game state. We will implement this functions in the following chapters, but for now they are here to better illustrate the situation.

SnakesAdventure.as from now on contains only variables and constants that are common to all three files or specific to code in this file. Init and UpdateFrame are the same as before, but Draw, MouseDown, MouseUp and MouseDown have been changed completely.

private function Draw(elapsedTime:Number):void
{
  switch (state)
  {
  case GAME_MENU:
    Draw_GameMenu(elapsedTime);
    break;
  case GAME:
    Draw_Game(elapsedTime);
    break;
  }
}

private function MouseDown(event:MouseEvent):void
{
  switch (state)
  {
  case GAME_MENU:
    MouseDown_GameMenu(event);
    break;
  case GAME:
    MouseDown_Game(event);
    break;
  }
}

private function MouseUp(event:MouseEvent):void
{
  switch (state)
  {
  case GAME_MENU:
    MouseUp_GameMenu(event);
    break;
  case GAME:
    MouseUp_Game(event);
    break;
  }
}

private function MouseMoved(event:MouseEvent):void
{
  switch (state)
  {
  case GAME_MENU:
    MouseMoved_GameMenu(event);
    break;
  case GAME:
    MouseMoved_Game(event);
    break;
  }
}

As you can see, all four functions looks very similar. They just check current state of the program and call appropriate function.

We have made some huge changes in the source code of the project and now we are set to implement new features. In spite of all this changes, program behaves exactly the same as it did before. You can verify this with embedded SWF below.


No comments:

Post a Comment