IT tutorials

Windows Phone 7 : Building 2D Games with the XNA Framework (part 2) - AlienShooter Game Structure

4/26/2013 9:54:29 PM
- Windows 10 Product Activation Keys Free 2019
- How to active Windows 8 without product key
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
1. Content Project

When you create a new XNA project, it always creates two projects, one project for your game and the other for your content. The Content project provides compile-time processing for game assets, including detecting missing assets, asset conversion, compression, and pre-processing. The key component to the Content project is the Content Pipeline.

1.1. Content Pipeline

The content pipeline does the work of preparing assets for use within an XNA Framework game. Assets are processed in two steps. The first step is importing the content. For the majority of formats, XNA has Content Importer classes to convert content into a common intermediate format. The second step converts the imported content into a final compiled, compressed, format via a Content Processor.

1.2. Importing the Content

Importing content is as simple as adding new items to the Content project. In most cases, the content pipeline automatically detects the asset type and assigns the correct Content Importer and Content Processor. It is also possible to create custom Content Importer and Content Processor classes for assets not supported by the built-in classes.

HeroShip = this.Content.Load<Texture2D>("Sprites/heroship");
SpaceShip = this.Content.Load<Texture2D>("Sprites/spaceship");
Missile = this.Content.Load<Texture2D>("Sprites/missile");

Each content item is loaded into a single texture. When drawn, each item requires its texture to be loaded by the GPU and rendered. The above items are drawn to the screen with these three lines of code in the Draw method:

spriteBatch.Draw(SpaceShip, SpaceShipPosition, Color.White);
spriteBatch.Draw(Missile, MissilePosition, Color.White);
spriteBatch.Draw(HeroShip, HeroShipPosition, Color.White);

Loading each texture is a performance hit for the GPU. A better way is to load a single texture that contains all of the images, and then just tell Draw which area of the texture to draw for that item. This type of texture is called a sprite sheet and is very common to use in game development, especially when creating sprite animation. There are two challenges with using sprite sheets: you have to take all of your individual images and mash them into a larger image, and you have to remember which part of the single large texture contains the particular image you want to draw to the screen.

Luckily AppHub comes to the rescue again with a ready-to-go custom Content Importer and Content Processor that can take a collection of images and automatically turn them into a single sprite sheet, solving the first challenge. For the complete background on the sample, download it here:

The sample also includes a runtime class to include in your game named SpriteSheet, which allows either named or indexed access to images so that you do not have to remember the exact pixel location, solving the second challenge listed previously.

Right-click the References folder in the AlienShooterContent project, select Add Reference, choose the Projects tab, and select the SpriteSheetPipeline project. Next, right-click on the References folder in the AlienShooter project and select Add Reference, choose the Projects tab, and select the SpriteSheetRuntime (Phone) project.

In the AlienShooterContent project navigate to the Sprites folder and exclude from the project these assets: heroship.tga, missile.tga, and spaceship.tga. We don't want to add the textures twice, so they should not be included as individual assets any more. Next, right-click on the Sprites folder and select Add | New Item... and choose XML File with a name of AlienShooterSpriteSheet.xml. Listing 1 shows the edited XML file.

Example 1. AlienShooterSpriteSheet.xml Sprite Sheet XML File
<?xml version="1.0" encoding="utf-8" ?>
  <Asset Type="System.String[]">

If you don't edit the file correctly, you will get a compile error if the SpriteSheetPipeline Content Processor cannot find an asset listed in the XML file. Notice in this example that the folder location is included relative to the AlienShooterContent project to correctly identify the asset location. Figure 7-3 shows the Solution tool window with the AlienShooterContent project expanded and the Properties dialog for the AlienShooterSpriteSheet.xml.

Notice in Figure 1 that the individual sprite images are hidden and not part of the project in the Sprites folder, though they need to be accessible in the file system to the SpriteSheetProcessor Content Processor so that it can turn them into a single sprite sheet. The only content that is part of the Sprites folder is the AlienShooterSpriteSheet.xml XML file. Also in Figure 7-3, notice that the custom SpriteSheetProcessor Content Processor is configured for the XML file. Let's now draw update the GamePlay screen to start to render our new AlienShooter assets. A using SpriteSheetRuntime statement is added to the top of the GamePlay.cs code file. Three new private fields are added at the top of the GamePlayScreen class:

SpriteSheet alienShooterSpriteSheet;
Texture2D backgroundTexture;
Rectangle screenRect;

The alienShooterSpriteSheet variable will let us render the entire sprite sheet to the screen for debug purposes. The backgroundTexture variable represents our game background as with the HelloXNA sample and the screenRect variable holds a variable that points to the Rectangle object that is the size of the draw area.

Figure 1. Solution and Content project after SpriteSheet modifications

The LoadContent method is updated to load the alienShooterSpriteSheetSpriteSheet and backgroundTextureTexture2D variables:

alienShooterSpriteSheet = content.Load<SpriteSheet>("Sprites/AlienShooterSpriteSheet");
backgroundTexture = content.Load<Texture2D>("Textures/background");


Most of the code in the Update and HandleInput methods is commented out since we no longer want the place holder code. The placeholder draw code is modifiedin theDraw method, and the following two additional items are added to draw the backgroundTexture and the alienShooterSpriteSheet to the screen:

//Draw background
spriteBatch.Draw(backgroundTexture, screenRect, Color.White);
//Draw Sprite Sheet
  new Rectangle(screenRect.Width / 2, screenRect.Height / 2,
                alienShooterSpriteSheet.Texture.Width / 2,
                alienShooterSpriteSheet.Texture.Height / 2),

Everything should compile and the game now shows AlienShooter assets on the GamePlayScreen, as shown in Figure 2.

Figure 2. AlienShooter SpriteSheet and background textures

Notice how tightly the Hero Spaceship, Missile, and Alien Ship are automatically packed in Figure 2 by the custom Content Processor. Just to close the loop, the code to draw an individual image from the AlienShooterSpriteSheet is very simple. Here is the code to just draw the Hero Spaceship at a point in the middle of the screen:

    new Vector2((screenRect.Width / 2)-
                alienShooterSpriteSheet.SourceRectangle("heroship").Width / 2,
                          (screenRect.Height / 2)-
                alienShooterSpriteSheet.SourceRectangle("heroship").Height / 2),


There is a verbose computation to create a Vector2 for the screen center minus the center of the Hero Ship, but otherwise it is the standard Draw(texture, Vector, SourceRectangle, Color) method. Notice how easy it is to identify the Rectangle on the alienShooterSpriteSheet where the Hero Ship resides. Just pass in the asset name and the SpriteSheet class will locate it. 

When you download the SpriteSheet Sample from AppHub, it includes an example extension on how to add a compression option to the Content Processor. Unfortunately the extension does not work for the XNA Game Studio 4.0 Reach profile. It just works for the HiDef profile.

The "Reach" profile limits XNA Game Studio to a subset of functions supported on Windows Phone, Xbox, and Windows for maximum compatibility. The "HiDef' profile supports only Xbox and Windows. It includes support for custom HLSL shaders as well as additional features.

We dive into creating a more robust game below but first let's cover some of the other constructs for a real game such as displaying game status text and menus, which is covered in the next section.

2. Text and Menus

Displayed text, such as game status and menus, is an important component of game development. Users want a nice clean menu system to navigate. Game status is critical to game play; it makes the game interesting such as how much life is left, high score, rounds of ammunition available, and the like.

There are two methods to display text in the XNA Framework. The first is via the SpriteFont class. The SpriteFont class leverages the built in Font classes on your PC to create the font texture to display letter character images when rendered. The SpriteFont class is covered in the next section.

The other method to display text in the XNA Framework is with customized bitmap fonts. This method is more advanced, which means it is highly customizable but also requires additional work. 

2.1. SpriteFont

The SpriteFont class takes a built in font and rasterizes it based on configuration parameters. To add a text Font for rendering in XNA Game Studio, right-click on the FontsSampleContent project and select Add => Item... => select Sprite Font, and enter a name. Usually, you name the Sprite Font item the same as the Font Name. If you include multiple sizes append the size to the end, which will make more sense in a bit.

While we take fonts for granted when working in Microsoft Word or in Outlook, fonts are licensed content. You must have redistribution rights to include a font in your game. Search the Web for "purchase fonts online" and quite a few sites show up. Some include free fonts with others for purchase.

Luckily XNA Game Studio 4.0 includes a set of OpenTypefonts you can use in your games. Figure 3 shows the fonts that are licensed by Microsoft for your use. The image is taken from the AppHub education catalog.

Figure 3. Fonts provided by XNA Game Studio for use in XNA framework games

For our sample, name the new Sprite Font item SegoeKeycaps24 and click Add. A new item named SegoeKeycaps16.spritefont is added to the FontSampleContent project. What may surprise you is that the SegoeKeycaps16.spritefont file is an XML file. Listing 1 shows the contents of the newly added file.

Example 1. SpriteFont XML File Format
<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">
    <FontName>Segoe UI Mono</FontName>
    <!-- <DefaultCharacter>*</DefaultCharacter> -->


The XML file describes the parameters for what should be rendered when text is drawn using this SpriteFont. For our example, change the FontName element to Segoe Keycaps. Change the Size to 16 and leave everything else at the default values.

You can edit the Spacing element to increase the space between characters, as well as modify the UseKerning item to modify how the font is laid out. Kerning adjusts the spacing between characters to be more pleasing to the eye. An example of kerning is when a capital "W" overhangs a neighboring "e" slightly when typing the word "Well." Without kerning, letters do not overhang or underhang as the case may be. The Style element indicates whether it should be Regular, Bold, or Italic.

The last element to discuss is the CharacterRegions element. CharacterRegions element controls what letters are available in the font. The default range is 32 (ASCII space) to 126 (ASCHII '~'). This reduces the number of characters rasterized as part of the content import process.

To draw the SegoeKeycaps16 Sprite Font, add a new private member named segoeKeycaps16 of type SpriteFont to the Game1 class in the FontSample project. Next add this line of code to the Game1.LoadContent method:

segoeKeycaps16 = Content.Load<SpriteFont>("SegoeKeycaps16");

We used the SpriteBatch.Draw method to draw textures to the screen. The SpriteBatch.DrawString method has six overloads to provide flexibility in drawing text to the screen. Here are a couple of examples:

spriteBatch.DrawString(segoeKeycaps24, text, new Vector2(24, 130), Color.Yellow);

spriteBatch.DrawString(segoeKeycaps24, text, new Vector2(24, 450), Color.Orange,
    -.25f * (float)Math.PI, Vector2.Zero, 3, SpriteEffects.None, 0);


You can tinge the font color by adjusting the fourth parameter with a color value such as Color.Yellow. The second DrawString call above applies a –negative 45 degree rotation in the fifth parameter and a 300 percent scale in the sixth parameter, with an orange tinge applied to the Sprite Font. Another font is added to the project named Miramonte with Italics style and a few more DrawString calls are in the code but Figure 4 shows the results.

Figure 4. DrawString examples with the SpriteFont class

The scaled font renders pretty well but you can see some stretching in the letter "e" in Figure 2 that could be more obvious with other fonts. In the next section we cover how to create a bitmap font.

2.2. Bitmap Fonts

Bitmap fonts are not dependent on a built-in font. Instead, the fonts are loaded from a texture similar to what is shown in Figure 5.

Figure 5. Bitmap font texture example

The example in Figure 7-7 was copied from MSDN by zooming in the browser by 200% and taking a screenshot, but you can create a custom bitmap font texture using any drawing program by following the conventions specified in the documentation.

The character order matters, with a space as the upper-left character. You can use a solid white or black background color for monochrome characters. In the previous example, black is used as the background color. Multicolored characters are supported with an alpha channel.

The space between characters must be filled with Magenta color (Red:255 Green:0 Blue:255 Alpha:255). The FontTextureProcessor class is applied to the texture instead of the default processor. The FontTextureProcessor will pack the characters in as close as possible so you don't have to worry about exact spacing between characters.

The bitmap font texture in Figure 6 is added to the BitmapFontSampleContent project with a name of BitmapFont.bmp. The Content Processor is configured to Sprite Font Texture - XNA Framework from the default of Texture - XNA Framework.

The SpriteFont class is still used as the member type for the bitmapFont object and the bitmap font is loaded in LoadContent just like for a regular SpriteFont content:

SpriteFont bitmapFont;
...//Load Content
bitmapFont = Content.Load<SpriteFont>("BitmapFont");

Drawing is the same as well with the DrawString method:

spriteBatch.DrawString(bitmapFont, text, new Vector2(24, 70), Color.White);

In summary, the primary differences when using a custom bitmap font is that you must draw out the characters correctly in the proper order and you configure the Content Processor to Sprite Font Texture - XNA Framework for the bitmap font texture.

2.3. MenuScreen Class

The MenuScreen class is part of the GameStateManagementSample (Phone) sample project. It is the base class for the MainMenu.cs and OptionsMenu.cs screen objects that are part of the AlienShooter game project.

The MenuScreen class takes advantage of a helper class named MenuEntry, which draws the text and publishes a Selected event. The MenuEntry class does not detect the touch. Instead, the MenuScreen does most of the work to draw, detect a touch, and associate the touch with the correct MenuEntry item. A good way to understand how this works is to look at the constructor for the MainMenuScreen class:

public MainMenuScreen()
    : base("Main Menu")
    // Create our menu entries.
    MenuEntry playGameMenuEntry = new MenuEntry("Play Game");
    MenuEntry optionsMenuEntry = new MenuEntry("Options");

    // Hook up menu event handlers.
    playGameMenuEntry.Selected += PlayGameMenuEntrySelected;
    optionsMenuEntry.Selected += OptionsMenuEntrySelected;

    // Add entries to the menu.

The MainMenuScreen class creates the menu entries and associates event handlers with the menu entries. The base class MenuScreen handles the animation and positioning. A developer can customize the animation and layout by modifying the base MenuScreen class.

One way to customize the menu screens is to change the Font in the AlienShooterContent project. Open the /GameManagement/menufont.spritefont file and change the FontName element to Quartz MS from Figure 6 and change the Size to 24. The font has a science fiction look to it, which suites a game named AlienShooter pretty well.

We also modify the GamePlayScreen class to have Score and Lives text across the top with a SlateBlue color background. This is achieved via the SpriteBatch.DrawString method as well as adjusting the background color to SlateBlue and drawing the backgroundTexture 34 pixels lower via the added backgroundPosition Vector2 object. Figure 6 shows both the updated menu screen and game play screen.

Figure 6. Updated Menu and Game screens for AlienShooter

When you run the project on a device, the animations and transitions look pretty nice. These can certainly be customized as well once you understand how to create animations and transitions in XNA Game Studio. We cover both topics in detail to create the actual game play.

- Windows Phone 7 : Building 2D Games with the XNA Framework (part 1)
- Android Application Development : Signing and Publishing Your Application (part 2)
- Android Application Development : Signing and Publishing Your Application (part 1)
- iPhone Developer : Assembling Views and Animations - View Hierarchies
- iPhone Developer : Creating an “Online” GameKit Connection
- Java ME on Symbian OS : Handling Transitions Between Foreground and Background
- Java ME on Symbian OS : Handling JSR Fragmentation
- IPad : Using Popular and Critical Apps - Using Bento
- IPad : Using Popular and Critical Apps - Using iTap VNC
- BlackBerry Development : Pushing Data to Internal Users - Browser Push
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
programming4us programming4us
Popular tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS