XNA Game Studio 4.0 Programming: The Game Object and the Default Game Loop
When you create a new project, many things happen behind the scenes, and many features to help drive the game available to you. In this chapter, you learn about these features, including:
- The game class
- The standard game loop
- Game components
Up until now, you've created new projects and added some code to do other fancy things, but you haven't taken a step back to look at the default game template. Now is a good time to take a look at what is provided for you automatically and the other features available.
What Is in a New Project?
Open Visual Studio and create a new Game Studio 4.0 Windows Game project. Notice that your main project includes two code files (program.cs and game1.cs), and you have a content project you previously used. You can safely ignore everything in program.cs because it is simply the stub that launches the game. As a matter of fact, this isn't even used on Windows Phone 7.
The interesting things that are discussed in this chapter are in game1.cs. Notice first that the Game1 class that is created comes from the Game object provided by Game Studio. The initial starting project gives you everything you need to start creating a game. It has a spot for initialization, a spot to load the content your game needs, a spot to update the game state, and a spot to render everything.
More things happen behind the scenes than you are probably aware of, however. Start with the first thing you see in the constructor, creating the GraphicsDeviceManager.
graphics = new GraphicsDeviceManager(this);
This one line of code starts a chain reaction of operations. It naturally creates a new GraphicsDeviceManager (which is discussed in just a moment), but it does more than that. This object implements IGraphicsDeviceService and IGraphicsDeviceManager. When you create the object, it takes the game parameter you've passed in (that is, the this parameter) and adds itself to the Services property of the game object.
After the graphics device manager has been added to the services list, the actual graphics device is created when the constructor has finished executing. The default options work just fine, but you actually do have some control over the settings the device has.
Notice that quite a few different properties on this object can be used to control how the device is created or to get information about it. The first one is the GraphicsDevice. Right now, it hasn't been created yet, but after it has been, it can be accessed here. You most likely never need it, though, because the GraphicsDevice is a property of the Game itself.
The GraphicsProfile is another property you can access. Profiles are discussed in Chapter 4, "Introduction to 3D Graphics". Next is the IsFullScreen property that behaves differently depending on the platform you run. The default value here is false, although on Xbox 360, it doesn't matter what this is set as because you are always full screen on that platform. On Windows, setting this to true causes the device to be created in what is called full screen exclusive mode, and your rendering encompasses the entire screen. On Windows Phone 7, this controls whether the system tray bar is visible or not visible.
The next set of properties is the most commonly changed, and it includes the preferences. Because they are preferences and not requirements, the runtime attempts to use these settings, and if it cannot use them, it falls back to what it feels is the closest to what you requested. These properties are PreferMultisampling, PreferredBackBufferWidth, PreferBackBufferHeight, PreferBackBufferFormat, and PreferDepthStencilFormat.
The back buffer is where your content is rendered, and the sizes in these preferences (width and height), control how large that area is. On Windows, in nonfull screen mode, this also controls the size of the window. In full screen mode, it controls the resolution of the monitor when it takes exclusive control of it. On Xbox 360 and Windows Phone 7, the devices have a built-in native resolution. For Windows Phone 7, the device has a resolution of 480x800 (in portrait mode), whereas the Xbox is configurable. On each of these platforms, if you ask for a different back buffer resolution, it is scaled to the native device resolution.
Multisampling is the process used to remove what are called the "jaggies" from rendered images. These jagged edges are formed normally on the edges of objects or on lines that are not on pixel boundaries (for example, nonhorizontal or vertical lines). Multisampling blends each pixel with other pixels around it to help soften these jagged edges. It does this by rendering the image larger and blending multiple pixels down to a single pixel. Although it doesn't necessarily remove the jagged edges, it certainly can help. There is a performance cost for doing this, so this defaults to false.
The last two preferences are the formats for the back buffer and the depth stencil. Formats are used to describe how data is laid out for the final rendered image. For the back buffer, this is how the color is laid out, and the default for this is actually SurfaceFormat.Color. This is a 32-bit format that has 8 bits for red, green, blue, and alpha. The depth stencil buffer formats control how many bits are used for the depth buffer and stencil buffer.
The last two properties are SupportedOrientations, which is mainly used for Windows Phone 7, and SynchronizeWithVerticalRetrace. Synchronizing with the vertical retrace is a way to prevent tearing by pausing until the device is ready to render the entire screen at once. These are discussed in depth in Chapter 11, "Understanding Performance" when performance and measurement are discussed.
There are also six different events you can hook off of the graphics object, most of which are self-explanatory based on the names. The one interesting one is PreparingDeviceSettings. This event is triggered right before the device is created, and it gives you the opportunity to override any of the settings before the device is actually created. Use this only if you know the device supports the settings you request.
There are also two methods on the object, ApplyChanges which attempts to instantly update the device to the current settings (or create a new device if required), and ToggleFullscreen, which makes a windowed game full screen and a full screen game windowed during runtime. Using either of these is rarely required.
The last thing the constructor does is set the root directory of the automatically created content manager to "Content," which is where your content project places the content you add to your game. The content manager is created for you when the game is created, so you can begin using it immediately. The content manager is discussed more in depth in Chapter 9, "Using the Content Pipeline."
Content.RootDirectory = "Content";
The default template has overrides for five common methods: Initialize, LoadContent, UnloadContent, Update, and Draw. Although nothing happens in Initialize and UnloadContent, the other three have basic stub code. The LoadContent method creates the sprite batch object you almost certainly need. The Draw method clears the screen to the infamous CornflowerBlue color. Finally, the Update method adds a quick check to see if you're pressing the Back button on your controller to see if it should exit the game. We get into the flow of these methods and how they're used in just a moment, but first, let's take a look at the Game class itself.