Sign in to follow this  
chefgon_ign

How to separate code for different parts of a game (title screen, menu, gameplay)?

Recommended Posts

I've made a few little demo projects, but I've always had trouble when it comes time to separate the game into different modes. Start on a title screen, go to a menu or start the level, then show a status screen after the level and start a new level. Most of my games never get past the single-level demo stage because it becomes very difficult to direct the game to do anything else except the gameplay once the game engine is up and running. This pertains specifically to C++, C#, and Java.. but overall its just a general programming question. How do you guys switch from title screen to menu to level to next level?

Share this post


Link to post
Share on other sites
I would use a variable called 'level' which changes depending on which level you are playing. The 'level' variable can, for example represent the filename that the program is going to load from a file. Separating the gameplay from the menu can be done in a simple way using a switch statement in the game loop like this.


// suppose we have a variable called gameType
switch (gameType) {
case 0: {
// draw menu screen
} break;

case 1: {
// status screen, show different things depending on the level
} break;

case 2: {
// gameplay, draw player etc..
} break;
}



This is the way I use to do it, hope it helps..

Share this post


Link to post
Share on other sites
Using a state machine of course [grin]


There are essentially 3 types of state machines: Stack-based, flat (the classical FSM), and hybrid types.

Stack-based machines are usefull when the transitions tend to be of the "go deeper, then back out" variety, because they implicitly record the order of transitions and can be freed when popped from the stack. A good example would be a menu system.

Flat FSMs don't typically preserve any information about the order in which states were visited, although you could write one that did. They're good for more dynamic transitions and when you don't particularly care about traversing back down the series of transitions you came from.

Hybrids are essentially a stack of flat FSMs. Transition order is not recorded within the flat FSMs, only when transitioning between them.


Currently I'm using a stack-based FSM in my application, and its working well. I can push, pop and set the top stack element and I have a parameter stack used for communication between states. There are hooks for managing resources as well: when a state is pushed onto the stack its resources are loaded and the previous state unloads any unnecessary resources. Because resources are reference counted and centrally managed, only resources currently needed will remain in memory and only those resources that are not already loaded will be loaded at this time.

Share this post


Link to post
Share on other sites
There are a lot of solutions to it. One of them is to have a main loop where each level gets started and when its done you move to the next one. You could make a script language to assign the game levels.

Ultimatly its a little vague, its important that you use OOP in your case, and that you ensure there is only one loop running in the game, and basically just have that loop start each level and when its done let it return a true and move on to the next level. But its all dependant on what for a game you want to make.

In my case we made a scripting language to do all of this sort of stuff :)

Share this post


Link to post
Share on other sites
Quote:
Original post by chefgon_ign
Most of my games never get past the single-level demo stage because it becomes very difficult to direct the game to do anything else except the gameplay once the game engine is up and running.
Use function pointers or a big switch statement in your game hub. I myself only have a few states, so I use a switch in my game class that calls different functions.

My main loop calls the Update(dt) function of my CGame class, and in there it goes through a switch statement to get to the correct current game mode. All game modes have a menu (I store all my menus in an array, and set the proper gui menu to be the active one when switching modes). Every mode will render it's menu, and do any other background / object rendering as needed.

If the user clicks on a button that causes the mode to change, than I set the new mode, change the active menu, or do any other state changes that need to be done, and that's it.. the next time the CGame.Update(dt) function gets called, it just calls the code for the current game mode.

EASY.

Share this post


Link to post
Share on other sites
What I did when I was working on some mobile games, was writing a class for every separate menu and gamescreen. The gamescreens would load a specified level and handle the gameplay. All of these screen classes derived from a single class, and a display manager would store a reference to such an object, so you could swap screens whenever you wanted, and the display manager would simply continue displaying the new screen, whether it was a menu or game screen.

What I'm currently doing is loading a level from a script file, and providing some scriptable game entities that can flush the current level data and load a new one. I treat menu's as levels too, in terms of scriptability: when you click on the Start Game button, it activates a levelchange entity, that loads the first level, just like the changelevel entity in level 1 loads the script file of level 2. The only difference between a menu level and a real level is that the first has a 2D background and no player, and the second loads a 3D environment and inserts a controllable player.

I hope this will give you some idea's. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Vampyre_Dark
Use function pointers or a big switch statement in your game hub.
Or, if you're actually writing C++, then you use an abstract base class something like the following:


class IGameState
{
virtual void render() = 0;
virtual void update(float timestep) = 0;
};


and then derive your individual game states from it. The 'dispatcher' (the game loop) then only needs a pointer to the current IGameState that it can call functions on. It's basically identical to the function pointer approach, except that ties all function pointers for a given state together into one table (the vtable for the appropriate state object).

Share this post


Link to post
Share on other sites
Quote:


Or, if you're actually writing C++, then you use an abstract base class something like the following:



class IGameState
{
virtual void render() = 0;
virtual void update(float timestep) = 0;
};

This is something like what I am using right now. So far, I love it...it is very easy to handle navigation... (below is the base state class definition).

//ZState.h
#ifndef ZSTATE_DEF
#define ZSTATE_DEF

#include <d3d9.h>

class ZStateManager;

class ZState{
public:
virtual bool update(float x){ return false; };
virtual void render(LPDIRECT3DDEVICE9 pd3dDevice){ };
virtual void init(LPDIRECT3DDEVICE9 pd3dDevice){ };
virtual void close(LPDIRECT3DDEVICE9 pd3dDevice){ };
};

#endif



I do have a question on this though. I have seen before where someone used static functions, not objects, for a state-machine. I believe that adding a new state also took a void** parameter, (which if I'm not mistaken is a pointer to a pointer, thus could be anything). Is this better than using classes, or is it probably more of a personal preference?

Share this post


Link to post
Share on other sites
Before everyone gets you off course of what you want to do, I suggest getting an introduction book to Object Oriented Programming. After you have ravenously chewed that book apart (because you are a programmer, right?), check out the Gang of Fours' book on OO pattern designs.

I'm not associated with GoF, I just found their book really useful.

Share this post


Link to post
Share on other sites

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