Sign in to follow this  

[.net] game state manager

This topic is 4197 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i understand that for a game to go from Intro -> Main Menu -> GamePlay -> GameOver -> MainMenu a Game State Manager would be the best solution. But i have no idea as how to write a Game State Manager. Could someone pls show me some sample codes or tutorials? (preferably in C#) Thanks in advance.

Share this post


Link to post
Share on other sites
I based my game state manager on the the Managing Game States in C++ article.

The article is more of an insiprational source. It reqires a bit of tweaks to get it useful IMO.

Here's the code for the game state components from the engine of my not yet released and kind of postponed open source C#/MDX game:


// +---------------------------------------------------------------------------+
//
// Copyright © 2006 Martin Nordholts. All rights reserved.
// Website: http://www.chromecode.com
//
//
// File: AbstractGameState.cs
// Created: 2006-01-23
//
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// +---------------------------------------------------------------------------+

using System;

namespace Chrocodile
{
/// <remarks>
/// Represents a base class for game states. Derive gamestates from this class.
/// </remarks>
public abstract class AbstractGameState
{
/// <summary>
/// Resets the game state. Called by <see cref="GameStateManager"/> if the pushed game
/// state doesn't exist in the game state stack.
/// </summary>
public virtual void Reset()
{
}

/// <summary>
/// Updates the gamestate.
/// </summary>
public abstract void Update();

/// <summary>
/// When a gamestate is taken over by another gamestate (for intsance when the user is in a game
/// and then switches to the menu, without quiting the game) this method gets called on the game
/// gamestate.
/// </summary>
public virtual void Pause()
{
}

/// <summary>
/// When a gamestate gets focus again, this method is called.
/// </summary>
public virtual void Resume()
{
}

/// <summary>
/// Gets called when the last instance occurence of a task is popped.
/// </summary>
public virtual void Stop()
{
}
}
}




// +---------------------------------------------------------------------------+
//
// Copyright © 2006 Martin Nordholts. All rights reserved.
// Website: http://www.chromecode.com
//
//
// File: GameStateManager.cs
// Created: 2006-01-23
//
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// +---------------------------------------------------------------------------+

using System;
using System.Collections.Generic;

namespace Chrocodile
{
/// <remarks>
/// This class handles the diffrent gamestates.
/// The GameStateManager keeps a stack of game states, where only the 'top' GameState is updated.
/// This allows several layers of GameStates, menu :: game :: menu :: highscores (i.e. looking at the
/// highscores in the middle of a game).
/// The stack is managed in a 'smart' way. Read comments on the methods for futher info.
/// </remarks>
public class GameStateManager
{
/// <summary>
/// Updates the game state on top of the stack.
/// Called by <see cref="GameStateManagerTask"/>.
/// </summary>
public void Update()
{
stackOfGameStates.Peek().Update();
}

/// <summary>
/// Pushes an abstract game state on top of the stack. If the gamestate is
/// already in the stack, its Reset() method is not called. This allows us to
/// create logic chains of game state, for instance menu::game::menu::topscores
/// without menu being reseted the first time it gets pushed.
/// </summary>
/// <param name="abstractGameState">The game state to push onto the stack.</param>
public void PushGameState(AbstractGameState abstractGameState)
{
// If the stack already contains a game state this must be paused before we
// add the new one.
if (stackOfGameStates.Count > 0)
stackOfGameStates.Peek().Pause();

// If the game state that we add already is in the stack, we must Resume() it.
// Otherwise we reset it.
if (stackOfGameStates.Contains(abstractGameState)) {
abstractGameState.Resume();
} else {
abstractGameState.Reset();
}

stackOfGameStates.Push(abstractGameState);
}

/// <summary>
/// Pops the active game state from the stack,
/// </summary>
public void PopGameState()
{
AbstractGameState poppedState = stackOfGameStates.Pop();

// If this was the last occurence, stop the gametstate.
// Otherwise just Pause()
if (stackOfGameStates.Contains(poppedState)) {
poppedState.Pause();
} else {
poppedState.Stop();
}

// Resume the stack below
if (stackOfGameStates.Count > 0)
stackOfGameStates.Peek().Resume();
}

/// <summary>
/// Pops all gamestates until the specified gamestate is at the top of the stack.
/// Typically called from a game over state to fall back to a menu state.
/// </summary>
/// <param name="abstractGameState"></param>
public void PopGameStatesTo(AbstractGameState abstractGameState)
{
while (stackOfGameStates.Peek() != abstractGameState || stackOfGameStates.Count == 0) {
PopGameState();
}
}

/// <summary>
/// Pops all game states.
/// </summary>
public void Deinitialize()
{
while (stackOfGameStates.Count > 0)
PopGameState();
}

private Stack<AbstractGameState> stackOfGameStates = new Stack<AbstractGameState>();
}
}



This structure works well for the simple game I am writing, you might want to futher improve this code. I'm not even sure the code is bugfree, but I guess it will help a bit.

Share this post


Link to post
Share on other sites
Have a look at Chad's CUnit framework over at C-Unit. He implemented a nice (at lesat IMHO) game state manager. Basically, as Enselic already shoed in his post, you create an abstract BaseGameState class. Then for every gamestate you create a class which inherits from the BaseGameState class.
The different gamestates are kept in a stack structure of BaseGameState objects. Thus, let's say you're currently in the MainGameState and you hit Escape. This intantiates a new GameState of type MenuGameState. This state is pushed on top of the GameStates stack. When you return to the game you pop the last GameState from the stack. Because all GameStates inherit from the same base class, all you have to do is always call the Render/Update etc... method of the topmost GameState of the Stack. The runtime will then call the correct method of the currently active gamestate.

Well I hope I've been clear. Anyway, have at look at the CUnit framework. It really helped me.

Share this post


Link to post
Share on other sites
I've made this point before on similar threads, but you might want to have a game state manager and a menu manager, so you can have the menu overlain above the current position of the game, if there is one.

Share this post


Link to post
Share on other sites

This topic is 4197 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this