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.
-
This question may be identical to http://gamedev.stackexchange.com/questions/1783/, but I'm not sure what you mean by mini-states.
My answer to the question (http://gamedev.stackexchange.com/questions/1783/game-state-stack/1785#1785) 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.
The Communist Duck : 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.Joe Wreschnig : My point is that such things are not necessarily different in a system using state-sets.softCoder : 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.Joe Wreschnig : 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.softCoder : Hm...Ok :) But I have for example something like that: pseudocode : class Game <>---- class Map (Game has Map) mapstates; 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 ? From Joe Wreschnig -
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.
Joe Wreschnig : 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.Ipsquiggle : 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.munificent : 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).Joe Wreschnig : 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.From munificent -
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.
From Kylotan
0 comments:
Post a Comment