Adding Menu or Game State to game

Started by
6 comments, last by POLSKASH 18 years, 10 months ago
How would I go about adding a menu or any game state to my game? Basically, is there an easy way to handle game states because I can't seem to get anything to work. Here is an example of my Main function:

int main(int argc, char *argv[])
{
	init();

  //Main loop: loop forever.
  while (Done != 1)
  {
	Game();
  }
  Shutdown();
  return 0;
}

Thanks, Chris
Advertisement
Primitive:
Create an int var and then #define the different Gamestates and create within the main loop an if/else-if/else-if blah to check which Gamestate is currently active and do there the stuff which needs to be done. After that's done set the next game state.

You should actually check trough the articles section here and/or on flipcode as there are a few articles on this topic provided for sure.

But you should also get to a nice and quick solution by thinking on your own and thinking of what the purpose of game states is and how you could use them.

cheers,
Marcel
I'm not for sure but,I think you need to end your loop before you shut down.
so I would do:
if(gamestate == shutdown)
{
done = 1;
}
hope that helps!
I do it like this:

(c++)
enum gamestate{ MENU, PLAYING, HISCORE, QUIT };bool running=true;// Codewhile(running){   while(gametate==menu)   {       DrawMenu();       HandleMenuEvents();   }   while(gamestate==PLAYING)   {   // Playing code   }   // etc.}
This is not good if because most mainloops look somewhat like this...

while(running)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//If there are no winmessages, put the idle code here
GameLoop();//-->does something and ends then
}
}

...but you do this ...

while(running)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//If there are no winmessages, put the idle code here
while(gamestate==PLAYING)
{
//blahcode
}
}
}

... so you get stuck with your while and no winmessage are proceeded...

actually I think that it is so ...


Hope I didn't blame you by mistake ... if so please correct me :)

cheers,
Marcel
A finite state machine is what you want.

Basic example (based on your game loop):
#define STATE_1 1#define STATE_2 2#define STATE_3 3#define STATE_4 4#define STATE_5 5…int state;int main(int argc, char *argv[]){	init();	state = STATE_1;//Main loop: loop forever.  	while (Done != 1)  	{		switch( state ) {		case STATE_1:			…			break; 		case STATE_2:			…			break; 		case STATE_3:			…			break; 		case STATE_4:			…			break; 		case STATE_5:			…			break;		…  	}  	Shutdown(); 	return 0;}


Usually the switch is placed in your Game() function, and from there it calls out to specialized functions based on the state.

Good luck
My site shows how to handle game states with stacks and function pointers. Here's the link:

Aaron's Tutorials

Check out the function pointers tutorial and the intoduction tutorial to the 2d game programming series. It's a bit more complicated than a switch statement, but I've got a lot of positive feedback about it.

-Aaron
-------------------------------See my tutorial site: Click here
I have a relatively simple method for handling gamestates, allow me to share:

I have a pure virtual GameState class that looks like this:
class GameState{public:    virtual bool Run() = 0;};


Then, you derive from it. Say you make a TitleScreen class:
class TitleScreen : public GameState{public:     TitleScreen(int* purp);//Send a pointer to your purpose integer, so that                            //once this state is finished, you can switch to                            //another state.     virtual bool Run();     private:     int* purpose;//Somewhere in the constructor, purpose = purp;};


In the TitleScreen class, you implement Run(). That is where you will have your Windows message loop. Sometime or another, you will want that gamestate to be finished. Before the Run() function in TitleScreen returns false, you must remember to set your current game state integer to the next state that you want. In my example, the one player game is designated to the integer value 1, so you would do *purpose = 1;

Then I have another class that just encompasses my entire game. For example:
class PongGame{     public:          bool Run();     private:          GameState* currentGameState;          int* purpose;//Really, this should be an enumeration for clarity.};


Here is what the bool PongGame::Run() function looks like:
bool PongGame::Run(){     if(!currentGameState->Run())//current gamestate finished                {          switch(*purpose)          {          case 0://Say this is to quit               return false;               break;          case 1://Say this is to take you two the one player game or something               currentGameState = new TitleScreen(purpose);               return true;               break;          };     }}


Then, my WinMain function looks something like this:
WinMain(blah){     WindowsClass* winClass = new WindowsClass(hInstance);//My windows Class that just sits on its own basically          PongGame* PongG = new PongGame(blah);          while(PongGame->Run())     {}     return 0;}


It's definately not the best set up, but it worked perfectly well for my Pong Clone. Just try it.



There are some things so stupid that only an intellect could believe them.

This topic is closed to new replies.

Advertisement