Ryan Wahle wrote:
I like this idea alot. . . So basically it would be a huge switch
statement correct? Tell me if this is correct:
Special Moves
DOWN LEFT
LEFT RIGHT
LEFT DOWN LEFT
DOWN UP DOWN
int state;
key = GetKeyboardInput();
switch (state)
case START_STATE:
if (key = DOWN)
state = DOWN;
if (key = LEFT)
state = LEFT;
else
MovePlayer();
case DOWN:
if (key = LEFT)
special move();
if (key = UP)
state_down = UP;
switch (state_down)
case UP:
if (key = DOWN)
special move();
and the same for the other moves also… and i would need to set the state
to START_STATE again if no special move has been found…
Is this correct?
In a sense, you got it right that it is a “huge switch statement”, but
your implementation doesn’t have the right smell… Specifically, the
second switch inside the first one has nothing to do there.
This is a simple table.
For example, say you have UP, DOWN, LEFT and RIGHT, as well as a SPIN
special move which is activated by doing LEFT RIGHT LEFT successively:
State 1: initial state
if key == UP -> 2
if key == DOWN -> 3
if key == LEFT -> 6
if key == RIGHT -> 5
else -> 1
State 2: up
do the “up” stuff
-> 1
State 3: down
do the “down” stuff
-> 1
State 4: left
do the “left” stuff
-> 1
State 5: right
do the “right” stuff
-> 1
State 6: move1-left1
if key == RIGHT -> 7
-> 4
State 7: move1-right
if key == LEFT -> 9
-> 5
State 9: move1-left2
do the “spin” stuff
-> 1
See how it works? So you have a “state” variable that say where you’re
going next time you get into the switch. Note that this is very useful
for simple AI with multiple “bots”, as you can easily go thru that
switch once for each bot, with each of them having their own state
variable. For example:
int monster1_fsm(int state) {
switch(state) {
case 1:
bla bla;
return next_state; /* you probably have more than one of these */
case 2:
bla bla;
return next_state;
}
}
Then, in your main loop:
int i;
for(i = 0; i < num_monster1; i++)
monster1[i] = monster1_fsm(monster1[i]);
This will “run” the monster 1 AI for all the monster 1 active in the
game.
Many people consider games as graphics, tiles, sprites and so on, but I
tend to see two main things in games: the input, the state machines and
the main loop which ties them together.
One last hint: it helps a lot to have some kind of event system with
state machines, as you won’t have a single “if” statement, but plenty of
them scattered over multiple state machines. Consider time to be an
event. Some basics:
enum EventType {
EV_KEY,
EV_MOUSE,
EV_JOYSTICK,
EV_NETWORK,
EV_TIME
};
struct Event {
enum EventType type;
struct Event* next;
};
struct Event_Key {
/* those need to be the same as “struct Event” /
enum EventType type;
struct Event next;
/* key event specific info here */
…
};
Then you need a queue of events. The main loop will wait for some input
to happen and sends the according event (or a time event if too much
time without input passed by, use poll() or select(), with their timeout
parameter for this). When an event happen, you go through the state
machines, then go back to wait for the next event.
A good place to do the redrawing is after the state machines, before
looping to the event wait, as you can have the state machine change a
variable when something needs to be redrawed, and do it right at the
end. If nothing needs to be drawn, just skip the drawing part.–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/
“First they ignore you. Then they laugh at you.
Then they fight you. Then you win.” – Gandhi