How would one call a state change?

Sep 18, 2011 at 1:25 AM
Edited Sep 18, 2011 at 4:57 AM

Nevermind I got it.

For those interested, you have to make your states' constructors with room for your gamestatemanager, which you'll pass along and then trigger based on gui input or keys or however you want to set it up. In mine, it was this:

Game.gs
       

 protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(this.GraphicsDevice);

            //This is for example purposes only and must be updated.
            playerTexture = Content.Load<Texture2D>(@"Textures\Player");

            Viewport viewport = GraphicsDevice.Viewport;

            //Gamestate Management
            mainMenuGameState = new MainMenuGameState(graphics, this.GraphicsDevice, this.Content, spriteBatch, guiManager, inputManager, gameStateManager);
            inGameGameState = new InGameGameState(graphics, this.GraphicsDevice, this.Content, spriteBatch);
            gameStateManager.Push(inGameGameState, GameStateModality.Exclusive);
            gameStateManager.Push(mainMenuGameState, GameStateModality.Exclusive);
            gameStateManager.Switch(mainMenuGameState);
        }

 

Then, in mainMenuGameState.cs,

        private void createDesktopControls(Screen mainScreen)
        {

            // Button to open the "New Game" dialog
            ButtonControl newGameButton = new ButtonControl();
            newGameButton.Text = "New Game";
            newGameButton.Bounds = new UniRectangle(
              new UniScalar(1.0f,-90.0f), new UniScalar(1.0f, -120.0f), 100, 32
            );
            newGameButton.Pressed += new EventHandler(newGameButton_Pressed);
            mainScreen.Desktop.Children.Add(newGameButton);

        }

        void newGameButton_Pressed(object sender, EventArgs e)
        {
            gameStateManager.Pop();
        }

And that got it going. Hope this helps someone!

(I understand there's a way to pass along the entire services class to the gamestate, and for how many things I'm passing, I wonder if that wouldn't be more efficient?)

Coordinator
Sep 18, 2011 at 10:07 AM

Hi! Glad you figured it out :)

I think the way you're handling the dependencies here is the best choice there is.

Passing around the IServiceProvider is generally not such a good idea (google "Service Locator AntiPattern") because it hides the dependencies of a class (you don't know what needs to be put in that IServiceProvider unless you read the source code or gave 100% accurate documentation) and forces you to write boilerplate code for picking the services from the provider.

If the constructors end up taking too many arguments (say, more than 3), you can always create more specialized classes (say, a SceneManager that contains a series of SceneEntities any automatically loads content and takes care of drawing, thereby replacing the IGraphicsDeviceService, SpriteBatch and ContentManager references).

To make work even easier, you could use an inversion of control (IoC) container like Ninject or Microsoft Unity. I have an example project on my website: http://www.nuclex.org/downloads/articles/51-xna-dependency-injection-demo

 

Sep 18, 2011 at 1:35 PM

Great, I'll look into it. Thanks for the help and the terrific framework!

Sep 19, 2011 at 12:38 PM
Edited Sep 23, 2011 at 12:54 PM

Got another question for you: how would I go about passing events from child to parent in the UI? Using my example above, lets say I've got mainMenuGameState.cs which calls SinglePlayerDialog.cs, and SinglePlayerDialog.cs has a "START" button that should pop the gamestate stack and clear all UI elements. Player chooses their options and hits "START." I've written a function into mainMenuGameState that will handle this start button call, but I can't figure out how to get it from the child into the parent, so all the desktop controls are still visible even in the inGameGameState. Any tips on how to get this to work? 

 

Sorted this too(just passed the statemanager).