Game state machine (Rendering question)

Recommended Posts

f8k8    171

Share on other sites
Guest Anonymous Poster
Whoever owns the states should call both states' Render method during a fade?

Share on other sites
f8k8    171
But shouldn't it be up to the state itself to decide what to render? I'd like to have a more general solution, so that a state can do other things like layer itself on top of another state's rendered output (e.g. a message box or something).

Share on other sites
Telastyn    3777
Personally, I'd look towards a decorator sort of pattern here.

class FadeTransition:State{    private State From;    private State To;    public override void Update(){        if(To.alpha!=255){            // increment fade        }else{            // This might be tricky, depending on how you're            //  doing things.            Exit();        }    }    public override void Render(){        From.Render();        To.Render();    }       public override void Exit(){        Iterator MyGameStatePosition=GameStates.Find(this);        if(MyGameStatePosition.IsValid()){            MyGameStatePosition=To;            // possibly unreference To.        }        // possibly delete this/from.    }    public FadeTransition(State FromState, State ToState){        Iterator FromGameStatePosition=GameStates.Find(FromState);        if(FromGameStatePosition.IsValid()){            FromGameStatePosition=this;        }        From=FromState;        To=ToState;        // Set fade effect data.    }}

Share on other sites
Guest Anonymous Poster
I dont think if my methoid is right either,in my game loop i have something like:

if(in_game)
{
process_game();
render_geometry();
}
{
}

here i can make the game so it can play at the same time I am in the menu(for example in multiplayer game without a Pause button) . I may do additional check in process_game() for the menu variable and lock the in_game controls if necessary.

Share on other sites
nilkn    960
I recommend doing something along the lines of what Telastyn has suggested. Take the fade logic out of the states, and relegate it to a specific fading mechanism. In an OO design, the states should be as modular and self-contained as possible.

Share on other sites
Huge_    122
I like you state system - I've just moved over to something like that myself. Also including functions "OnMouse" and "OnButton" etc. in the state.
One way to do multiple states is to use something like "PushState" as well as "SetState". So you are in the game, and you press the "Options" button, you "PushState" to the options dialog - this leaves both states active to some extent. The "Options" state can do soemthing like "if there is a parent state, render that first, now render myself over the top". When you press the "ok" button, you "pop state". This works well for re-using the options dialog from the main menu as well as in game. Also works well for pausing etc. within the game.
Not too sure about fading, but when you leave a state, you could save a bitmap and alpha it away to 0 over a certain amount of time.
In answer to your question about calling each others render, you could do it a bit like I described above, with "GetBaseState()->Render()" style, or simple have the state objects call a third object to do the rendering - after all, you are going to need a "GameData" object separate from any of your states. ie, "gGameData->DrawMap()", thereby not doubling up on your drawing code

Share on other sites
Bob Janova    769
IMHO, states should be self-contained and not have to worry about what other states may or may not be present. That can get complicated surprisingly quickly, apart from ideological arguments.

I agree with Telastyn's idea of having a transition class which manages a fade (or, indeed, any other transition).

For a state stack, I think the onus is on the stack to render each state in order. A dialogue-box state should only render itself, leaving whatever was there before still visible outside it's own window space. Something like (C#):
Stack states;void RenderStates(){ for(int i = 0; i < states.Count; i++)  (states[i] as State).Render();}