XNA Creators Club Online
Page 1 of 1 (6 items)
Sort Posts: Previous Next

Access an object from several Screens on State Management Sample

Last post 05-05-2008 5:44 PM by Baltico X. 5 replies.
  • 05-04-2008 2:20 AM

    Access an object from several Screens on State Management Sample

    Hi, I am extending the Network State Management sample for my game. It is a multiplayer turn based board game.

    Before a session is created, the player must specify some parameters like which side of the table he wants to play, and how many minutes he desires to play; in order to find a proper match. 

    I created a class called "TableOptions" that handles and stores the chosen parameters, and ultimately defines the values of a public property of type "NetworkSessionProperties". I also derived a new class called "TableOptionsScreen" from the "MenuScreen" to let the user set the parameters.

    I need to be able to access the public property of type "NetworkSessionProperties" from the "CreateOrFindSessionScreen" screen class, and also from my "TableOptionsScreen" class. And probably, as I go on developing, I will need to access the "TableOption" object from the "GameplayScreen" class, to retrieve some of the values that were set before the session was created.

    My question is: where is the best place to create and expose a TableOptions object?

    Certainly if I do it as a public property in the "ScreenManager" class, It will work, but I don't know if that is a good design approach, so I would like to listen some opinions.

    Thanks in advance.

  • 05-04-2008 1:04 PM In reply to

    Re: Access an object from several Screens on State Management Sample

    You could register your TableOptions object as a service and then you can get access to it from anywhere you need it.

     

  • 05-05-2008 12:18 AM In reply to

    Re: Access an object from several Screens on State Management Sample

    Thanks David. I will be honest, I had no idea that I could add services to my game until I received your reply. In fact, I had to browse a lot, and read a lot of stuff, and brush on C# interfaces until I could actually make it work.

    I will post how I did it so others can benefit, but first, there is something that still bothers me. I had to get a reference to the service in the draw method of my screen; because when I tried it on the constructur the ScreenManager object returned null, so I could not get the Game reference either.

    This is how I did it:

    * Created an Interface from my existing TableOptions class, it was easy, just right click on the class name, select Refactor, and then select Extract Interface.

    * Then added this line of code on my game constructur, just after all the Components.Add calls.

    Services.AddService(typeof(ITableOptions), new TableOptions());

    * Third, created a global variable on my TableOptionsScreen class, as follows

        class TableOptionsScreen : MenuScreen
    {
    ITableOptions tableOptions;

    * Then got a reference to it using the following line. I am not completerly happy because I had to do this on the Draw method and not on the constructor. But it works really nice.

    tableOptions = (ITableOptions)ScreenManager.Game.Services.GetService(typeof(ITableOptions));
    * Finally, used the tableOptions object as I wished, preserving values between calls and being available on all the screens, yes!!!
    menuEntry = new MenuEntry(tableOptions.SitColorNamed);

    Well, I learned a lot and I think that the Game.Services functionality is a great tool to keep a nice software architecture.

    Thanks again.

  • 05-05-2008 1:08 AM In reply to

    Re: Access an object from several Screens on State Management Sample

    I just want to post a quick follow up reply to present some additional possibilities.  It sounds like you basically need an object that stores some settings/preferences values that will be used in multiple places in your game.  Instead of making it a service you could just store the instantiated class object variable in the ScreenManger class since you already ensure that you have a reference to the ScreenManager.

    However to avoid the problem of not being able to use the ScreenManager field in the constructors, you probably need another way to access the class.  You could make the class static or make the fields within the class static (as long as you only need one instance of the class).  Additionally, the way I did it was to implement my settings class as a Singleton (implementation info here).  It's similar to having a static class but I think it's nicer to work with a singleton.  Then you would access your fields by doing something like this:
    menuEntry = new MenuEntry(TableOptions.Instance.SitColorNamed);

    This would allow you to access that class anywhere and you wouldn't be limited by the ScreenManager reference.

  • 05-05-2008 10:34 AM In reply to

    Re: Access an object from several Screens on State Management Sample

    A better place to get the reference you need might be in the LoadContent method. Within the GameScreen paradigm, LoadContent and UnloadContent are more equivalent to Initialize and Shutdown methods. So, for those that don't like doing things in LoadContent that aren't actually loading content, it might help to think of it that way. If it still bothers you, you could add Initialize and Shutdown methods to the GameScreen interface and call them appropriately from the ScreenManager.

    Good job with your research! A lot of people would have turned this into a multi-page thread asking question after question that could be answered with a bit of reading. Your initiative is to be commended. :-)

     

  • 05-05-2008 5:44 PM In reply to

    Re: Access an object from several Screens on State Management Sample

    Phil, thanks a lot. I agree that the the singleton approach will be a good choice if all I need to do is to store some preferences and access them on several places, and also thanks for the link, it helped me to better undestand the concept.

    I will stick with the game service approach just for the sake of learning more about the XNA object model, but hopefully I will have the chance try out your approach as well as the development goes on.

    David, thanks again, I will move the code that gets the reference to the service to the LoadContent method, that will be ok.

Page 1 of 1 (6 items) Previous Next