Xna game state tutorial
With this next sample you're going to be introduced to classes, objects, polymorphism and events! You shouldn't be, any words you get stuck on just do a quick search online and read about it. It's one of the best ways to learn. Example 3 - Using polymorphism to make managing screen state just a little easier. You've seen screen state managed two different ways already, now let's get all object oriented on the issue and introduce the concept of classes and take advantage of polymorphism.
This is a much more advanced way of solving the same problem, but "advanced" doesn't necessarily mean it's a better solution. It's just always good to know and understand various ways of solving problems. The more tricks you have in your hat as a coder, the better off you and your games will be!
We'll start this example off the same way as the others. The first few steps are exactly the same as in the first sample. If you're not sure exactly how to do one of the steps below, just look at the sample above to jump start your memory. With that out of the way, lets start creating some of the base objects we're going to be using in our game.
Since we're working with "screens" in our game, we're going to create a Screen class to give us a nice object to work with in code. Add a new class to your game. Name the class "Screen". Once you've added the Screen class to your game, we need to start adding some code to the class. Without them you'd have to type something like Microsoft.
SpriteBatch every time you'd want to create a new SpriteBatch object. That's a lot of typing and less typing is a good thing sometimes!
With that added, let's start adding some functionality to the screen class. First, we're going to want a way to track the PlayerOne controller index. And we're going to want that tracking object to be available to all screens so they can use it when necessary.
We'll do that by creating a "static" PlayerIndex object in our Screen class. The "static" keyword means that every instance of our screen classes will have the same value, so changing it in one changes it for all screens.
Next, we're going to want a way for our screen to notify the main game class that something has happened. We'll do this by having an event handler who's value will be filled in when the Screen class is created. You can see that an EventHandler object is passed into the Screen constructor.
We then store that value in our ScreenEvent object in our class. With the constructor finished, lets add our remaining two methods to the class. All screens are going to have Update logic and Draw logic so we'll add "virtual" methods to the screen class that subclasses can override and add any specific Update and Draw code they have.
By making these methods part of our base Screen class, we'll be able to take advantage of a concept called "polymorphism" great subject to go read up on if you're unfamiliar with the term!
And that's it for our screen class. Not much to see right now, but we're not quite done yet! Now that we have our base screen class let's start making some of our specific screen objects. We want to have a controller detect screen in our game, so let's go ahead and create a new class called ControllerDetectScreen. Once you have that new class added to your game project, add the following "using" statements to the top of the class. Next we're going to want to indicate that our ControllerDetectScreen is inheriting from our base Screen class so you'll need to modify your class line to look like the following.
With our code setup to indicate that we are inheriting from the Screen class, let's start adding some code specific to our ControllerDetectScreen. We'll start by adding our background texture and then writing the code for our constructor to load the texture and pass on the event handler to the base class.
The Update logic for the ControllerDetectScreen class is going to be eerily familiar to the update methods we wrote in the previous two samples. The logic remains the same, the only real difference is that instead of changing to a new screen state we're invoke our ScreenEvent and notifying the main game class that something happened in the ControllerDetectScreen. Next up is our Draw method. Again, this is going to look very similar to the draw methods you wrote for the controller detect screen in the previous two samples.
Add a new class to your game and call it TitleScreen. Once you have that created, add the following "using" statements to the top of the class.
We want our title screen to also have the behaviors and properties of a screen so we need it to inherit from the base Screen class as well. Modify your class line to look like the following. The constructor for the TitleScreen class is basically the same as the constructor you wrote for the ControllerDetectScreen.
The only difference is that you're loading the TitleScreen background image. So we will need to add in the Update method and it's logic. Notice that when the current gamepad state is queried we're using the PlayerOne object as the player index we pass into the method. This means that whatever controller the player pressed "A" with on the ControllerDetectScreen will be stored in that value.
So if the player started the game with controller three, the controller three is what will be checked to see if the user pressed "B" to move back. And now we add our Draw method to visually display all the elements that make up our title screen. In this sample this doesn't consist of much, just a simple background image, but you could fill this method with everything that needs to be drawn in your own title screen.
So now we've created our base screen class Screen and our two screens that inherit from it ControllerDetectScreen and TitleScreen. But really, we still don't have anything to show for our effort. It's time to add some code to our main Game class to finally hook this all up. We'll start by adding some variables to the top our our Game class. We'll create one object for each specific screen type ControllerDetectScreen and TitleScreen and then we'll create an object called mCurrentScreen that is just our base Screen type.
You'll see how we'll be using that in just a minute remember polymorphism! We created the screen objects, but now it's time to load them. We'll be creating new instances of our ControllerDetectScreen and TitleScreen objects and we'll be passing in some specific events for each screen type we haven't created the events yet, but we'll pass in the names we're planning on using.
You'll notice that we set the CurrentScreen equal to the ControllerScreen. This is possible even though the Controller screen is of the ControllerDetectScreen type because it inherits form Screen. The only restriction when using this to your advantage is that you can't access any specific properties or method that re only in the ControllerDetectScreen class, you only have the base Screen methods and properties available to you.
Pretty neat trick huh? It gets even better in just a minute, but first we need to create those screen events! You saw in the ControllerDetectScreen class we wrote that we were "invoking" a screen event method and then when we created our ControllerDetect screen object just a minute ago we passed in a new EventHandler with this method named. This means that when the ControllerDetectScreen invokes the ScreenEvent method, this method will be fired.
You can then put any logic you want in the method. In our case, I'm switching the current screen variable to the TitleScreen indicating that our screen state has changed to a new screen.
Now we need to write a similar method for the Title screen event. Add the following method to the Game class in the Game1. In our Update method, we basically just want to make sure that the Update method is being called for the current screen.
And to do that, all you have to do is add a single line of code! Since the base screen class has an Update method, it's available to be called. How great is that! So add the following single line of code to the Update method in the Game class in the Game1. Can you guess what you need to do in the Draw method to make the current screen draw? Well, it's more than one line of code because we have to Begin and End our spriteBatch, but it IS just one line of code to draw the current screen.
Thank your object oriented programming! And that's it, we're all done with the sample! Go ahead and run it and watch it work. Again, no new functionality but we solved our screen state issue with yet another solution.
Think you could figure out how to add another screen class and make it work? In that folder we want to start with an interface that all the game states will be using. Some things we need to keep in mind is what do we want the game state to be able to do. We now need to set up a GameState class that all of our states will implement. Create a new class in the same subfolder called GameStateManager. The GameStateManager. We want to add this to the top of the class. So now the question is, what do we need the GameStateManager class to do?
We need to be able to add new GameStates to the stack, remove them, and update and draw the current one. Lets start with adding and removing GameStates. We want to add the following methods to the GameStateManager class. Almost forgot, one last method. With the SpriteBatch being passed in we now just have to call begin on it draw what we need to draw, and call end. Now that we have everything set up, we just need to add our new GameState to the manager so it can Update and Draw it.
In the LoadContent from the Game class after you set the content for the GameStateManager, you just need to add the following. Since the GameStateManager is a singleton you can call it from any class which will allow you to add, remove, and change states from anywhere at any point. This works really good with menus you can start at the main menu, then push the options menu on the stack, then pop the options menu off the stack to go back to the main menu.
This is part four of a four part series covering sprite movement. Part four covers adding the code to the project to make the Wizard sprite shoot fireballs. This tutorial covers the basics of creating and maintaing projectiles.
A tutorial developed to show how to achieve a fade in, fade out effect with a a 2D image. This tutorial walks you through creating a game project, adding an image to that project, displaying the image and adding the effect of fading the image in and out of the scene. Along with the tutorial and it's source code, there is an enhanced sample showing multiple images fading in and out of the scene Cheshire cat style which can be downloaded from within the tutorial.
A tutorial developed to show how to create an RTS style selection box. This tutorial walks you through creating a game project, adding an image to that project, displaying the image, making the mouse pointer visible and using the mouse to create a selection box.
Along with the tutorial and it's source code, there is an enhanced sample showing how you can use the selection box to select some simple "units" and move them around the game window. A tutorial developed to show the basics of how to create a Health bar.
This tutorail will walk you through creating a game project, adding an image to that project, tracking the current health level and displaying that appropriately with a health bar. If you're following the code along in the book, the images and source code provided here should help you finish the project out.
0コメント