Game State Management?
Monkey Forums/Monkey Programming/Game State Management?
| ||
Any thoughts on managing game state, eg. switching between title, options screen and the game itself? In my first largish app I have two case statements, one in Update() and the other in Render(), which each determine which state the program is currently in and then execute the correct function. I would like to possibly avoid doing it this way, maybe by creating a state class and having several different ones. I've read about people doing this with a stack of states. Anyone experienced with that? |
| ||
I do this with the following (better solutions probably out there). I have a ScreenManager Class [monkeycode]Class ScreenManager Global ActiveScreen:Screen Global Screens:StringMap<Screen> Function Init:Void() Screens = New StringMap<Screen> End Function Add:Void(tName:String, tScreen:Screen) Screens.Set(tName,tScreen) End Function Update:Void() If ActiveScreen <> Null ActiveScreen.Update() End End Function Render:Void() If ActiveScreen <> Null ActiveScreen.RendeR() End End Function SetScreen:Void(tName:String) ActiveScreen.OnEnd() ActiveScreen = Screens.Get(tName) ActiveScreen.OnStart() End End[/monkeycode] and I have a screen class [monkeycode] Class Screen Method OnStart:Void() End Method OnEnd:Void() End Method Update:Void() End Method Render:Void() End End[/monkeycode] and for each screen in the app I just create an extended instance of Screen [monkeycode]Class OptionsScreen Extends Screen End[/monkeycode] and I just overload the standard screen methods as required. In OnCreate() I do the following to add screens to the manager [monkeycode] ScreenManager.Init() ScreenManager.Add("game",New GameScreen()) ScreenManager.Add("logo",New LogoScreen()) ScreenManager.Add("options", New OptionsScreen()) ' Make the logo the first shown screen ScreenManager.Set("logo") [/monkeycode] and in the main OnUpdate() and OnRender() methods I just have ScreenManager.Update() and ScreenManager.Render() from within each screen just call ScreenManager.Set("screenname") to change the screen. |
| ||
I use polymorphism for the state machine and instead of using select/case I use NextState. each object assign the nextState based on the conditions met. it's a simple function that assigns the next state to the current state. each object such as menu, game, settings etc. extends from the GameState Class. similar to Raz. |
| ||
Each of my first three apps were basically one large state machine, which was a pain to maintain/enhance because everything was so inter-related. For my last app I implemented a Layer, Scene, SceneStack & Director system. Layers are added to Scenes, Scenes are pushed/popped (via the Director) to/from the SceneStack. The Director routes events/input to the Scenes on the SceneStack, and the Scenes pass the events/input onto their Layers. MUCH easier system to work with. |
| ||
A lot depends on the complexity of your app. for a simple app I would have (typically) three about states for the main window (e.g. title, normal play, main menu), and then the main menu would have its own sub-states / sub-menus, which the main window need not care about. There are typically other state elements during normal play, e.g. something is animating, or a level is starting. I may use state machines or booleans for those. So basically, nested state machines is my usual approach. |
| ||
I am using a state based game framework. It's still in development, but you can check out the code here to maybe get some ideas: http://code.google.com/p/mutated-monkey/source/browse/#hg%2Fwdw%2Fframework%253Fstate%253Dclosed Basically, engine, game and state are separated. The engine runs the game, the game runs and controls states. |
| ||
I actually used Raz's method. I'll be putting some other things in there like programmable fades and wipes between scenes but other than that it has most everything I want. Interesting how you see this concept of decoupling all over the place and how many benefits it offers. |