2
\$\begingroup\$

I'm not entirely sure how to ask this question since its somewhat broad, but also a bit specific to my code.

I'm making a game in C# XNA and attempting to have the parts of it be fairly modular so that they can be used in any other relevant programs I create down the road. For instance, I have an InputHandler accessible from any class in my program that simply checks the state of the keyboard and mouse and has various methods to find out specifically if a key / button is held down, pressed, or released, etc.

The groundwork of my program was made by following these tutorials: Part 1 Part 2 and Part 4

(Its not a mistake that I don't have a link to part 3 as that dealt with adding in Xbox 360 gamepad functionality only, which isn't something I needed in my testing.)

In those tutorials there is a GameScreen Game Component made which is what all the other screens / states inherit from.

The way the tutorial handles screen management is that a type of screen is created in the Game1 class and then only in the Game1 class can you Hide / Show a screen or change which screen is active.

For instance, when the program is first run in the LoadContent section of Game1 a StartScreen(which inherits from GameScreen) is created. The StartScreen is then set to be the ActiveScreen and is set to Show.

My problem is that in my StartScreen I'm handling the checks for what menu option a user selects, but I can't actually hide the current screen and change to the one that was selected because that can only be done from the Game1 class.

I could just handle all of my input checking for the different screens in the Game1 class by using an if statement based on not only what menu option is selected, but also what screen is active, but that would mean a lot of clutter in my Game1 class and it would kind of ruin my goal of making my game components modular by having all of the stuff relevant to a given screen being handled within that screens code.

My question is essentially what I should do to address this...

I tried several times to make a separate ScreenManager Game Component that is accessible from everywhere much like my InputHandler, but each time that ended in disaster with numerous errors that I simply don't have the experience or grasp on lingo to troubleshoot.

My most recent attempt at making a separate one ended with me being able to choose which screen was active, but not being able to use the ".Hide()" method that is part of the GameScreen base class. I also had numerous "accessibility" errors.

I also tried to simply make my screens themselves be public. For instance, in my Game1 class I have variables for GameScreen activeScreen and StartScreen startscreen. I've tried making those two variables be Public or even Public Static, but I still couldn't use them anywhere outside of Game1.

I've looked at numerous other posts and tutorials on making a Screen Manager or how to handle State Management, but that only served to confuse me more. They were either WAY over my head, like the Microsoft State Management sample, or they were understandable and working, but far too different from the one I have now for me to grasp how to apply it to my current code.

Is there something easy and obvious that I'm stupidly overlooking or is there some key concept at work that I'm unaware or failing to grasp?

Or am I going about it all in the wrong way entirely?

\$\endgroup\$
2
\$\begingroup\$

GameScreen Game Component made which is what all the other screens / states inherit from.

This is all you need to reference your Game1 class.

Each GameComponent has a property called Game, which is of type Game. Your Game1 is a subclass of Game, so it can be used to fill the property. And indeed it is used exactly that way when you call its constructor within your Game1:

GameComponent gameComponent = new GameComponent(this);  // "this" is your Game1 class

This property is accessible like so:

gameComponent.Game;

In order to retrieve the properties and methods of your subclass of Game, just cast it to your subclass:

Game1 game1Ref = (Game1)gameComponent.Game;

This is how each menu can cause the main class to update the active menu.

P.S.: I think if you study the GameStateManagement example a little more closely, you'll find those menu items are already able to update the active screen using C# event-type properties. Events, delegates, expressions, lambdas, yadayada are a complex part of the C# language, but you would do well to learn to use them. They are very handy.

Your tutorial seems to do something similar to the example content. But it also refers to XNA 3.0 and 3.1, neither of which is the latest (final) version. It might be better to study the more recent code example.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.