Click here to Skip to main content
Click here to Skip to main content

State Pattern in C++ Applications

, 13 Sep 2001
Rate this:
Please Sign up or sign in to vote.
Small game framework based on the state pattern.
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Introduction

The state pattern is very useful when you need an object to alter its behaviour when this object’s state changes. The purpose of this article is to give you an example of the State pattern in action. In that case, the State pattern has been applied to a small game framework.

During the last year, I have written some small DirectX games. One of the problems I’ve encountered was the transition between game states. For example, when the game starts, I was usually displaying an Introduction page on which you could see a menu showing my game options. Then, according to the user choice, I had to start the game, show the high scores or show something else. I’ve solved my problem by considering all those choices as states.

Below is a diagram showing my game logic built on the State pattern.

Class diagram

In the application class (CStatePattern_GameApp), we have a function called Run(), which provides a default message loop. Basically, this function updates the game and then processes all other messages. The Update function simply ask the view to render the current frame.

To avoid overhead, the DoFrame function will check if it needs to redraw something, according to the frame rate, or not. I won’t give too much detail on the frame rate stuff since this is not the purpose of my article. But if you are interested, all the code related to the frame rate stuff is located in the CStatePattern_GameView class.

Let’s get back to the State pattern. In the next section, I will explain what happens when the DoFrame function is called. There are two main parts in this function. The first thing that gets done is the game update. Usually, this is where you would update all game objects in the current state (ship position, collision detection, etc.):

	m_GameManager.Update();

The second part is the game rendering:

	m_GameManager.Draw(pDC /* device context */ );

The game manager holds a pointer to a CGameState object. Therefore, when we call the Update function of the CGameManager object, this will simply redirect the call to the current state object:

	 m_pGameState->Update(this);

This call represents a big part of the State pattern. As you can see, we are calling the Update function of the current state object, but we are also giving a pointer to ourselves as a parameter. The reason is that after performing state-specific work, the Update function of the current state object will be able to change the current state of the game.

An important thing to understand is that the CGameManager object doesn’t know a thing about the game. It is the CGameState subclasses that will define the game logic and each state transition as the game goes by.

The declaration above is really important. For example, let’s say that in our game, when the user hits the space bar, the ship fires. Basically, the CStatePattern_GameView will receive a key event. The view will simply redirect the event to the game manager. The game manager does not know anything about the game logic, so it redirects this event to the current state object. If PlayState is the current state, the KeyEvent function of that state will check which key was struck. In this case, it’s going to fire. If the current state would have been IntroductionState, this event could have had a totally different effect.

Transitions

State transitions are another important part of the pattern.

For example, the Update function of the CPlayState could check if the player has any ships left. If this is not the case, this function would call the ChangeState function of the CGameManager like so:

pGameManager->ChangeState(CGameOverState::Instance() /* singleton pattern */);
The states are not changed by the game manager, but by the state itself.

The declaration above might look strange, but when you think about it, it’s just logic. Let’s say that the player needs to press F1 to start a game while he is in the introduction page. The introduction page knows what to do when the user presses F1. In that case, it will tell the game manager to change the current state to PlayState.

Demo Project

In my demo project, I simply demonstrate some state transitions. When the game starts, we are in Introduction state. This state will wait for the user to press a key. According to the key pressed, the Introduction state will change the CGameManager’s state. F1 will switch to the CPlayState, and F2 will switch to the CHighScoreState.

In my demo project, I have made some TRACE calls to show you the details of each transition.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Daniel Larocque
Web Developer
Canada Canada
No Biography provided

Comments and Discussions

 
QuestionWhich UML Tool used ? Pinmemberanandarv24-Jan-05 20:14 
AnswerRe: Which UML Tool used ? PinmemberDaniel Larocque25-Jan-05 1:37 
GeneralSome special cases (the good one) Pinmembercedric moonen29-Nov-04 1:51 
GeneralRe: Some special cases (the good one) Pinmembercedric moonen29-Nov-04 9:26 
General!Some special cases Pinmembercedric moonen29-Nov-04 1:44 
GeneralState Pattern in C# Applications [modified] Pinmemberaxelriet19-Oct-04 22:12 
GeneralBusy-wait PinmemberRichard McGrath25-Jul-03 14:02 
GeneralState Pattern PinsussRajasekaran R3-Sep-02 3:19 
GeneralRe: State Pattern PinmemberBinarygb21-Sep-03 14:06 
GeneralA suggestion PinsussAnonymous18-Jul-02 20:43 
GeneralGood PinmemberNorm Almond17-Sep-01 22:38 
Generalthanx PinmemberAnonymous16-Sep-01 19:16 
GeneralRe: thanx PinmemberAnonymous17-Sep-01 17:54 
GeneralKeep patterning... PinmemberPaul Selormey15-Sep-01 20:34 
I have also recently used the state pattern combined with adaptor in a project. The adaptor pattern is used to manage several modes of the application
1. Scroll modes,
2. Zooming modes,
3. Panning modes,
4. Editing modes,
5. etc.
 
Now, the editing modes is managed by the state pattern
1. Select state
2. Polygon state
3. Polyline state
4. etc.
 
Design pattern really works and is practical. Keep patterning Smile | :)
 
Best regards,
Paul.
 

Paul Selormey, Bsc (Elect Eng), MSc (Mobile Communication) is currently Windows open source developer in Japan, and open for programming contract anywhere!
GeneralRe: Keep patterning... PinmemberNorm Almond17-Sep-01 23:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 14 Sep 2001
Article Copyright 2001 by Daniel Larocque
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid