5
\$\begingroup\$

Hi :) I want to ask what is the best way to deal with "mini-states" in game? For example I making game like Simcity, i can build buildings, roads, rails, or I can change something in economy. I am making something like:

enum
{
  ROAD_CONSTRUCT,
  BUILDING_CONSTRUCT
  VIEW_MAP
  etc..
}

and in the game loop big switch. But the code is getting big. Is there some solution for all popular languages? I am asking because I am writing in C++, AS3 and sometimes in C.

\$\endgroup\$
2
  • \$\begingroup\$ are you using this enum to decide which view is presented to the player? like in sim-city when you are adding plumbing you see the water-flow instead of seeing the buildings? \$\endgroup\$
    – lathomas64
    Commented Sep 9, 2010 at 18:50
  • \$\begingroup\$ I write for example SimCity, I writing something more simple. \$\endgroup\$
    – softCoder
    Commented Sep 9, 2010 at 19:54

3 Answers 3

7
\$\begingroup\$

In an OOP language, the standard answer is to use polymorphism:

// Current game state. Should *not* really be a global var.
// This is just for demonstration. The current state can be
// changed by setting this to a new instance of a class that
// inherits State.
State * state;

void gameLoop() {
    while (true) {
        state->update();
    }
}

class State {
public:
    virtual void update() = 0;
}

class ConstructRoadState : public State {
public:
    virtual void update() {
        // Do stuff...
    }
}

// Other states...

In C, you can accomplish the same thing using a callback for the current state.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I don't know if the polymorphic solution is for "OOP languages" or just some of them. It's what I'd do in C++, but in Python or another language with convenient higher-order functions I would just use callbacks again, and in new C++ compilers I might use functors, if I was only managing a single function. \$\endgroup\$
    – user744
    Commented Sep 10, 2010 at 6:13
  • \$\begingroup\$ Definitely this: I do it all the time and twinge with pain every time I cross code using switch for state handling... The advantage of this is also that you can have each state "store state", initialize, deinitialize, etc, when it transitions in and out. \$\endgroup\$
    – Ipsquiggle
    Commented Sep 10, 2010 at 22:33
  • 1
    \$\begingroup\$ Callbacks work in an OOP language too, but these "states" are likely to have some state of their own, which makes polymorphic classes a good fit (unless you're more comfortable with closures than most OOP programmers are). \$\endgroup\$
    – munificent
    Commented Sep 11, 2010 at 0:02
  • 1
    \$\begingroup\$ In Python there is no significant difference between a method and a function, so you can pass a bound method to a callback system and keep it unaware of your instance's state. C++0x also takes some steps in this direction with lambdas and functors; I have not played with it enough to know if it's a good idea to do that yet (which means it's not; compiler support for them is bad). I would only use a polymorphic type if my interface consisted of more than one function. \$\endgroup\$
    – user744
    Commented Sep 11, 2010 at 12:30
1
\$\begingroup\$

It sounds to me that the problem isn't the states but the way you're handling them.

Why do you need a big switch in the main loop? The only things that generally change are the mouse cursor and the click behaviour. Both of those should be wrapped up in separate functions.

\$\endgroup\$
0
\$\begingroup\$

This question may be identical to Game State 'Stack'?, but I'm not sure what you mean by mini-states.

My answer to the question (Game State 'Stack'?) works regardless of how "important" the state is. When states are sets rather than a single global or stack, you don't have to worry about one state unexpectedly excluding another. If you do want a convenient exclusion mechanism for state sets, you can use e.g. the top eight bits of the enumerated value to enforce state uniqueness. Thus states don't need to explicitly know about other states, but just compare their own masked bits to other active states.

\$\endgroup\$
5
  • \$\begingroup\$ I don't think the OP means states such as menu, gameplay, options. I think he means something in-game, such as 'overworld map', 'road view', 'underground view', et al. SimCity-esque. \$\endgroup\$ Commented Sep 9, 2010 at 19:00
  • \$\begingroup\$ My point is that such things are not necessarily different in a system using state-sets. \$\endgroup\$
    – user744
    Commented Sep 9, 2010 at 19:01
  • \$\begingroup\$ I think about in games mini-states. They aren't big states like GameScreen , MenuScreen etc, I think they are to small, to making classes for each other. \$\endgroup\$
    – softCoder
    Commented Sep 9, 2010 at 19:10
  • \$\begingroup\$ In a state-set system a state is just an enumeration mapping to a single function or set of functions. When it comes time to do the thing that varies per state (or mini-state), you just call all active state functions. It doesn't really get simpler than that, except by making it all explicit with a switch statement; but that is what you asked to get away from. \$\endgroup\$
    – user744
    Commented Sep 9, 2010 at 19:13
  • \$\begingroup\$ Hm...Ok :) But I have for example something like that: pseudocode : class Game <>---- class Map (Game has Map) map<State, pFunc> states; state = construct states[state](); I click somewhere on screen, where I want to build something, and how to make this building process in extern func ? \$\endgroup\$
    – softCoder
    Commented Sep 9, 2010 at 19:53

You must log in to answer this question.