« The State pattern and game development ( I ) | Inicio | The State pattern and game development ( III ) »

The State pattern and game development ( II )

As we explained in the previous post, we’ll try to manage the object’s behaviour as a collection of related states, so the entity that implements that collection of states ( or state machine ) will be able to transit from one state to another. So we’ll have a classs ( Bubble ) that aggregates a collection of objects ( the states ) and a graphic to manage its presentation ( a movieclip ).

We are going to implement a non-hierarchical, non-concurrent state machine. If you want to read a deeper essay about state machines, I strongly recommend to take a look at FlashSim or quantum-leaps ( thanks to Jonathan Kaye for the links ). We will try to make things as simple as possible for the shale of performance ( remember, we are developing a game ).

First, here are two UML diagrams ( statechart diagrams ):

The bubble statechart

The game world statechart

Let’s take a closer look at the last diagram. There can be seen the different states that we’ve defined:

1.- initGame: General game initialization.
2.- initRound: General initialization of each game round. There will be setted the exploded bubbles counter, the time counter,…
3.- gamePlay. The user is playing the game.
4.- endOfTime: The time is over. We’ll check is the player has exploded enough bubbles.
5.- defeat. The player has not exploded bubbles enough. Ohhhhhhh.
6.- newChallenge. We offer the player the chance to play again, or to leave the game. If the player chooses to play again, we’ll move to initRound, and if the player chooses to leave the game, we’ll move to endOfGame.
7.- endOfGame. The game is over. We can send the player score to a server side script, …

Well, now that the concept has been explained we’ll try to explain how the state machine works.

First of all, when we enter a state an action is executed. In the most common state machine implementation there are three actions for each state, one will be executed when entering the state, another one when the state is executed, and another one when we leave the state. In this example, we’ll try to make everything as simple as possible, for the shake of performance, and we’ll execute just one action for each state.

Each arrow represents a transition. Each state contains a collection of transitions. This transitions can be callbacks that return a Boolean value, so the state machine will move by the transitions that returns a value of true. Usually, these transitions evaluate a given property of the class, and return true or false. Let’s explain it a bit more.

The state machine is closely tightened to a timer. So with every tick of the timer, some logic is executed ( all the transitions that start at the actual state are evaluated ), and state machine will move using the first transition that evaluates as true. So it will move to another state, where ( when the next tick occurs ) it will execute that state action. And next, it will evaluate more transitions, and…

Before taking a look at some code, we’ll try to explain it better going back to the Bubble class ( and diagram ). Let’s remember that this class is not a MovieClip subclass, but a complex entity that aggregates its state machine, and a movieclip.

So, when we create an instance of this class, and we create and start its state machine, will be in the first state: initBall. So, the state action ( initBallAction ) will be executed, and this action will attach a movieclip, and place it on stage. Then it will set a class flag ( isInitFlag, for instance ) to true, and it will set another flag to false ( isOutOfBoundsFlag ). With every timer tick, the transitions associated to this state will be evaluated ( here, there’s only one transition, that starts at initBall, and ends at moveBall ). So if that transitions returns the value of isInitFlag, it will return true, so the state machine will transit to the next state ( moveBall ).

This state has three transitions: the first one , that ends at itself, aonther one that ends at outOfBounds, and another one that ends at destroyBall.

So these transitions will evaluate ( in order ) the following flags: isOutOfBounds== false; isOutOfBounds == true and isClickedFlag == true.

When this state action is executed, first, we’ll calculate the next position of the bubble. Then, we’ll check if that position is out of the stage ( that includes bouncing against the floor ). If the bubble is out of stage, well set isOutOfBounds to true. So, if the bubble as not gone out of the stage, that flag will still be false. So, the transition that will return true will be the one that moves the state machine to the same state ( isOutOfBounds == false ), so well enter again the same state, so we’ll calculate the next ball position again,….

If the ball goes out of the stage, the transition that ends at outOfBounds will be the one to return true. So, the state machine will move to that state, where we’ll change the ball position or its velocity, and then we’ll return again to the moveBall state.

In the next post, we’ll see the code to implement all this, but now, the most important thing is to understand that is the entity itself the one that, just checking the value of some internal flags, changes it’s behaviour. And that that behaviour is separated in a collection of different objects.

There will be more soon.