Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
XNA 4 3D Game Development by Example: Beginner's Guide
XNA 4 3D Game Development by Example: Beginner's Guide

XNA 4 3D Game Development by Example: Beginner's Guide: Create action-packed 3D games with the Microsoft XNA Framework with this book and ebook.

eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing
Table of content icon View table of contents Preview book icon Preview Book

XNA 4 3D Game Development by Example: Beginner's Guide

Chapter 1. Introduction to XNA

Microsoft's XNA Framework provides a powerful set of tools for building both 2D and 3D games for Windows, the Xbox 360, and the Windows Phone platforms. As an extension of the Visual Studio development environment, XNA provides developers with a set of free tools for these environments.

The XNA project templates include an integrated game loop, easy to use (and fast) methods to display graphics, full support for 3D models, and simple access to multiple types of input devices.

In this introductory chapter, we will do the following:

  • Review the system requirements for XNA development

  • Install the Windows Phone Tools SDK, which includes Visual Studio Express and the XNA 4.0 extensions

  • Examine the basic structure of an XNA game by building a simple 2D game

  • Explore a fast-paced rundown of 2D techniques that will provide a foundation for moving forward into 3D with XNA

Starting out a book on 3D game development by building a 2D game may seem like an odd approach, but most 3D games use a number of 2D techniques and resources, even if only to display a readable user interface to the player.

If you already have an understanding of 2D game development in XNA, you may want to glance over this chapter and proceed to Chapter 2, Cube Chaser – A Flat 3D World, where we begin building our first 3D game.

System requirements


In order to develop games using XNA Game Studio, you will need a computer capable of running both Visual Studio 2010 and the XNA Framework extensions. The general requirements are as follows:

Component

Minimum requirements

Notes

Operating System

Windows Vista SP2

or

Windows 7 (except Starter Edition)

Windows XP is not supported.

Graphics Card

Shader Model 1.1 support

DirectX 9.0 support

Microsoft recommends Shader Model 2.0 support as it is required for many of the XNA Starter Kits and code samples. The projects in this book also require Shader Model 2.0 support.

Development Platform

Visual Studio 2010

or

Visual Studio 2010 Express

Visual Studio 2010 Express is installed along with the XNA Framework.

Optional

Windows Phone

Windows Phone Development Tools, DirectX 10 or later, compatible video card

The Windows Phone SDK includes a Windows Phone emulator for testing.

Xbox Live

Xbox Live Silver membershipXNA Creator's Club Premium membership

Xbox Live Silver is free. The XNA Creator's Club Premium membership costs $49 for 4 months or $99 for 1 year.

Installing the Windows Phone SDK


Originally developed as a separate product, XNA is now incorporated in the Windows Phone SDK. You can still develop games for Windows and the Xbox 360 using the tools installed by the Windows Phone SDK.

If you have an existing version of Visual Studio 2010 on your PC, the XNA Framework templates and tools will be integrated into that installation as well as the Visual Studio 2010 Express for Windows Phone installation that is part of the Windows Phone SDK, which we are going to install now.

Time for action – installing Windows Phone SDK


To install Windows Phone SDK , perform the following steps:

  1. 1. Visit http://create.msdn.com/en-us/home/getting_started and download the latest version of the Windows Phone SDK package. Run the setup wizard and allow the installation package to complete.

  2. 2. Open Visual Studio 2010 Express. Click on the Help menu and select Register Product. Click on the Register Now link to go to the Visual Studio Express registration page. After you have completed the registration process, return to Visual Studio 2010 Express and enter the registration number into the registration dialog box.

  3. 3. Close Visual Studio 2010 Express.

  4. 4. Launch Visual Studio 2010 Express, and the Integrated Development Environment (IDE) will be displayed as shown in the following screenshot:

What just happened?

You have now successfully installed the Windows Phone SDK, which includes Visual Studio 2010 Express, the XNA Extensions for Visual Studio, and the Redistributable Font Pack provided by Microsoft for XNA developers.

Speller – Our first XNA game


If you have never used XNA before, it would be helpful to review a number of concepts before you dive into 3D game design. In most 3D games, there will be at least some 2D content for user interfaces, Heads-up display (HUD) overlays, text alerts, and so on. In addition, many 3D game constructions are really evolutions of 2D game concepts.

In order to provide both an overview of the XNA game template and to build a foundation for moving forward into 3D development, we will construct a simple game called Speller. In Speller, the player controls a small square using the keyboard. During each round we will generate a random set of letters, including the letters needed to spell a particular word. The player's job is to navigate through the forest of letters and hit only the correct ones in the right order to spell the indicated word.

By building this game, we will be:

  • Performing initialization when our game is executed

  • Adding graphical assets to the game and loading them at run time

  • Displaying 2D images with the SpriteBatch class

  • Drawing text to the screen with the SpriteFont class

  • Colorizing images and fonts

  • Handling keyboard input and calculating player movement adjusted for the frame rate

  • Bounding box collision detection

  • Keeping and displaying the score

  • Generating random numbers

That is quite a bit of ground to cover in a very small game, so we had better get started!

Time for action – creating an XNA project


To create an XNA project, perform the following steps:

  1. 1. In the Visual Studio window, open the File menu and select New Project....

  2. 2. Under Project Type, make sure C# is selected as the language and that the XNA Game Studio 4.0 category is selected.

  3. 3. Under Templates, select Windows Game (4.0).

  4. 4. Name the project Speller (this will automatically update the Solution Name).

  5. 5. Click on OK.

The Speller game's Game1.cs file, when opened in Visual Studio, would look like the following screenshot:

What just happened?

We now have the skeleton of a project upon which we can build the Speller game. Each of the major XNA methods is declared, usually with no additional code except the execution of the method's base. We will examine each area of the XNA game template as we create the pieces necessary for Speller.

Managing content


Two separate projects get created when you start a new XNA Game Studio project in Visual Studio. The first is your actual game project, and the second is a special type of project called a content project. This is shown in the following screenshot:

Any non-code pieces of your game, including graphical resources, sounds, fonts, and any number of other item types (you can define your own content interpreters to read things such as level maps) are added to the content project. This project gets built along with the code in your primary project and the two are combined into a single location with everything your game needs to run.

When the content project is built, each item is examined by a content importer—a bit of code that interprets the raw data of the content file, a .jpg image for example, and converts it into a format that can be passed into a content processor. The content processor's job is to convert this file into a managed code object that can be stored on a disk and read directly into memory by XNA's ContentManager class. These compiled binary files carry the .xnb file extension and are located, by default, in a subdirectory of your game's executable folder called Content.

Note

ContentManager

Though its primary job is to load the content resources into memory at runtime, ContentManager does more than that. Each instance of ContentManager maintains a library of all of the content that has been loaded. If multiple requests to load the same content file are sent to a ContentManager instance, it will only load the resource from the disk the first time. The remaining requests are supplied with a reference to the item that already exists in memory.

Out of the box, XNA contains importers/processors for 3D meshes, images, fonts, audio, shaders, and XML data. We will create the content used for Speller with an image editor and the tools built into XNA Game Studio.

Time for action – creating content assets


To create content assets, perform the following steps:

  1. 1. Open Microsoft Paint, or your favorite image creation program, and create a new 16 x 16 image. Fill the image with white color and save the file to a temporary location as SQUARE.BMP.

  2. 2. Switch back to Visual Studio and right-click on the SpellerContent (Content) project in Solution Explorer.

  3. 3. Select Add | Existing Item... from the pop-up menu and browse to the SQUARE.BMP file. Select it and click on Add to add it to the content project.

  4. 4. Again, right-click on the content project in Solution Explorer and this time select Add | New Item....

  5. 5. In the Add New Item window, select Sprite Font from the window's center pane.

  6. 6. Enter Segoe14.spritefont as the name of the file and click on Add.

  7. 7. Close the XML document that appears after Sprite Font has been added to the project.

What just happened?

We have now added both an image and a font to our content project. We will see how we load these assets into the game at runtime and how we can use them during gameplay.

Note

Alternatives when adding content

You can also drag-and-drop files directly from Windows Explorer into the Solution Manager pane in Visual Studio to add them to your content project. If you have the full version of Visual Studio, you can add a new bitmap object by selecting Add | New Item... from the project's pop-up menu and selecting Bitmap as the type. The free version of Visual Studio does not support creating bitmaps from within Visual Studio.

The SpriteFont file that we created in step 6 and the XML document mentioned in step 7 actually load an XML template that describes how the content pipeline should create the resulting .xnb file. In this case, the default values for the SpriteFont template are sufficient for our game. This resulted in the Segoe UI Mono font (added to your system when the Windows Phone SDK is installed), with a value of 14 points being used. As we will only be using the standard A to Z character set, we do not need to make any changes to this template for Speller.

Member variables


Just after the Game1 class declaration in the Game1.cs file there are two class member declarations:

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch; 

These two members will provide access to the system's video hardware (graphics) and an instance of a class that can be used to draw 2D images and text (spriteBatch). We can add our own member variables here for things we need to keep track of while our game is running.

Time for action – declaring new member variables


Just after the graphics and spriteBatch declarations, add the following code snippet to include the new members:

SpriteFont letterFont;
Texture2D playerSquare;

Vector2 playerPosition;
Vector2 moveDirection; 
int playerScore;

Random rand = new Random();

string currentWord = "NONE";
int currentLetterIndex = 99;
class GameLetter
{
    public string Letter;   
    public Vector2 Position;
    public bool WasHit;
}
List<GameLetter> letters = new List<GameLetter>();
const float playerSpeed = 200.0f;

What just happened?

We have declared all of the member variables we will need for the Speller game. The letterFont member will hold the sprite font object that we added to the content project earlier, and work in conjunction with the predefined spriteBatch object to draw text on the screen.

The square image that will represent the player will be stored in the Texture2D member called playerSquare. We can use the Texture2D objects to hold graphics that we wish to draw to the screen using the SpriteBatch class.

The playerPosition Vector2 value will be used to hold the positions of the player, while moveDirection stores a vector pointing in the direction that the player is currently moving. Each time the player picks up a correct letter, playerScore will be incremented. Hitting an incorrect letter will cost the player one point.

An instance of the Random class, rand, will be used to select which word to use in each round and to place letters on the screen in random locations.

In order to keep track of which word the player is currently working on, we store that word in the currentWord variable, and track the number of letters that have been spelled in that word in currentLetterIndex.

The letters that are being displayed on the screen need several pieces of information to keep track of them. First, we need to know which letter is being displayed; next, we need to know the position the letter should occupy on the screen. Finally we need some way for our code to recognize that after we have hit an incorrect letter, we lose some of our score for it, but that we may spend several game update frames in contact with that letter and should not lose some of our score more than once for the infraction.

Note

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

All three pieces of information are wrapped into a child class of the Game1 class called GameLetter. If we were not intentionally keeping everything in Speller in the Game1 class, we would most likely create a separate code file for the GameLetter class for organizational purposes. Since Speller will be very straightforward, we will leave it inside Game1 for now.

As the GameLetter class defines a letter, we need a way to store all of the letters currently on the screen, so we have declared letters as a .NET List collection object. A List is similar to an array in that it can store a number of values of the same type, but it has the advantage that we can add and remove items from it dynamically via the Add() and RemoveAt() methods.

Finally, we declare the playerSpeed variable, which will indicate how fast the player's cube moves around the screen in response to the player's input. This value is stored in pixels per second, so in our case, one second of movement will move the character 200 pixels across the screen.

The Game1 constructor


The Game1 class has a simple constructor with no parameters. An instance of this class will be created by the shell contained in the Program.cs file within the project when the game is launched.

Note

The Program.cs file

When your XNA game starts, the Main() method in the Program.cs file is what actually gets executed. This method creates an instance of your Game1 class and calls the Run() method, which performs the initialization we will discuss shortly. It then begins executing the game loop, updating and drawing your game repeatedly until the program exits. In many games, we will not have to worry about Program.cs, but there are some instances (combining XNA and Windows Forms, for example) when it is necessary to make changes here.

By default, the constructor has created an instance of the GraphicsDeviceManager class to store in the graphics member, and has established the base directory for the Content object, which is an instance of the ContentManager class.

When we build our project, all of the items in the content project are translated into a format specific to XNA, with the .xnb file extension. These are then copied to the Content folder in the same directory as our game's executable file.

Our Speller game will not need to make any changes to the class constructor, so we will simply move on to the next method that is called when our game starts.

Initialization


Once the instance of the Game1 class has been created and the constructor has been executed, the Initialize() method is executed. This is the only time during our game's execution that this method will execute, and it is responsible for setting up anything in our class that does not require the use of content assets.

The default Initialize() method is empty and simply calls the base class' Initialize() method before exiting.

Time for action – customizing the Initialize() method


Add the following code snippet to the Ini tialize() method before base:Initialize():

playerScore = 0;

What just happened?

The only initialization we need to do is set the player's score to zero. Even this initialization is not strictly necessary, as zero is the default value for an int variable, but it is a good practice not to assume that this work will have been done for us.

Note

Initialize() versus LoadContent()

In practice, much of a game's initialization actually takes place in the LoadContent() method , which we will discuss next, instead of the Initialize() method. This is because many times the items we want to initialize require content assets in order to be properly created. One common use for the Initialize() method is to set the initial display area (resolution) and switch into full screen mode.

Loading content


After the Initialize() method has run, the LoadContent() method is called. Here, we initialize any items in our game that require the content assets we included in the content project.

Time for action – creating a square texture


Add the following code snippet to the LoadContent() method:

letterFont = Content.Load<SpriteFont>("Segoe14");
playerSquare = Content.Load<Texture2D>("Square");

CheckForNewWord();

What just happened?

The default Content object can be used to load any type of asset from our content project into an appropriate instance in memory. The type identifier in angle brackets after the Load() method name identifies the type of content we will be loading, while the parameter passed to the Load() method specifies the asset name of the content.

Asset names can be set via the Properties window in Visual Studio, but would default to the name of the content file, path included, without an extension. Since all of the content objects will be translated into .xnb files by the content pipeline, there is no need to specify the format that the file was in before it was processed.

In our case, both of our content items are in the root of the content project's file structure. It is possible (and recommended) to create subdirectories to organize your content assets, in which case you would need to specify the relative path as part of the asset name. For example, if the Segoe14 sprite font was located in a folder off the root of the content project called Fonts, the default asset name would be Fonts\Segoe14.

Note

Special characters in asset names

If you do organize your assets into folders (and you should!) your asset names will include the backslash character (\) in them. Because C# interprets this as an escape sequence in a string, we need to specify the name in the Content.Load() call as either "Fonts\\Segoe14" or @"Fonts\Segoe14". Two backslashes are treated as a single backslash by C#. Prefacing a string with the @ symbol lets C# know that we are not using escape sequences in the string so we can use single backslash characters. A string prefaced with the @ symbol is called a verbatim string literal.

The last thing our LoadContent() method does is call the (as yet undefined) checkForNewWord() method. We will construct this method towards the end of this chapter in order to generate a new word both at the beginning of the game and when the player has completed spelling the current word.

Updating


Our game will now enter an endless loop in which the Update() and Draw() methods are called repeatedly until we exit the application. By default, this loop attempts to run 60 times per second on the Windows and Xbox platforms, and 30 times per second on the Windows Phone platform.

The Update() method is used to process all of our game logic, such as checking for and reacting to player input, updating the positions of objects in the game world, and detecting collisions. The Update() method has a single parameter, gameTime, which identifies how much real time has passed since the last call to Update(). We can use this to scale movements smoothly over time to reduce stuttering that would occur if we make the assumption that our update will always run at a consistent frame rate, and code on other system events impacted by the update cycle.

Time for action – customizing the Update() method


Add the following code snippet to the Update() method before base.Update():

Vector2 moveDir = Vector2.Zero;
KeyboardState keyState = Keyboard.GetState();

if (keyState.IsKeyDown(Keys.Up)) 
    moveDir += new Vector2(0, -1);

if (keyState.IsKeyDown(Keys.Down))
    moveDir += new Vector2(0, 1);

if (keyState.IsKeyDown(Keys.Left))
    moveDir += new Vector2(-1, 0);

if (keyState.IsKeyDown(Keys.Right))
    moveDir += new Vector2(1, 0);

if (moveDir != Vector2.Zero)
{
    moveDir.Normalize();
    moveDirection = moveDir;
}

playerPosition += (moveDirection * playerSpeed * 
    (float)gameTime.ElapsedGameTime.TotalSeconds);

playerPosition = new Vector2(
    MathHelper.Clamp(
        playerPosition.X, 
        0, 
        this.Window.ClientBounds.Width - 16),
    MathHelper.Clamp(
        playerPosition.Y, 
        0, 
        this.Window.ClientBounds.Height - 16));

CheckCollisions();

CheckForNewWord();

What just happened?

During each frame, we will begin by assuming that the player is not pressing any movement keys. We create a Vector2 value called moveDir and set it to the predefined value of Vector2.Zero, meaning that both the x and y components of the vector will be zero.

In order to read the keyboard's input to determine if the player is pressing a key, we use the Keyboard.GetState() method to capture a snapshot of the current state of all the keys on the keyboard. We store this in the keyState variable, which we then use in a series of if statements to determine if the up, down, left, or right arrow keys are pressed. If any of them are pressed, we modify the value of moveDir by adding the appropriate vector component to its current value.

After all the four keys have been checked, we will check to see if the value is still Vector2.Zero. If it is, we will skip updating the moveDirection variable. If there is a non-zero value in moveDir, however, we will use the Normalize() method of the Vector2 class to divide the vector by its length, resulting in a vector pointing in the same direction with a length of one unit. We store this updated direction in the moveDirection variable, which is maintained between frames.

When we have accounted for all of the possible inputs, we update the player's position by multiplying the moveDirection by playerSpeed and the amount of time that has elapsed since Update() was last called. The result of this multiplication is added to the playerPosition vector, resulting in the new position for the player.

Before we can assume that the new position is ok, we need to make sure that the player stays on the screen. We do this by using MathHelper.Clamp() on both the X and Y components of the playerPosition vector. Clamp() allows us to specify a desired value and a range. If the value is outside the range, it will be changed to the upper or lower limit of the range, depending on which side of the range it is on. By limiting the range between zero and the size of the screen (minus the size of the player), we can ensure that the player's sprite never leaves the screen.

Finally, we call two functions that we have not yet implemented: CheckCollisions() and CheckForNewWord(). We discussed CheckForNewWord() in the LoadContent() section, but CheckCollisions() is new. We will use this method to determine when the player collides with a letter and how to respond to that collision (increase or decrease the player's score, advance the spelling of the current word, and so on).

The Draw() method


The last of the predefined methods in the XNA game template is Draw(). This method is called once after each call to Update() and is responsible for the game state for the current frame. By default, all that the Draw() method does is clears the display and sets it to the CornflowerBlue color.

Time for action – drawing Speller


To draw the visual components of our Speller game , perform the following steps:

  1. 1. Alter the GraphicsDevice.Clear(Color.CornflowerBlue) call and replace Color.CornflowerBlue with Color.Black to set the background color.

  2. 2. Add the following code after the call to clear the display:

    spriteBatch.Begin();
    spriteBatch.Draw(playerSquare, playerPosition, Color.White);
    
    foreach (GameLetter letter in letters)
    {
        Color letterColor = Color.White;
    
        if (letter.WasHit)
            letterColor = Color.Red;
    
        spriteBatch.DrawString(
            letterFont, 
            letter.Letter, 
            letter.Position, 
            letterColor);
    }
    
    spriteBatch.DrawString(
        letterFont, 
        "Spell: ", 
        new Vector2(
            this.Window.ClientBounds.Width / 2 - 100,
            this.Window.ClientBounds.Height - 25), 
        Color.White);
    
    string beforeWord = currentWord.Substring(0, currentLetterIndex);
    string currentLetter = currentWord.Substring(currentLetterIndex, 1);
    string afterWord = "";
    
    if (currentWord.Length > currentLetterIndex)afterWord = currentWord.Substring(currentLetterIndex + 1);
    
    spriteBatch.DrawString(
        letterFont, 
        beforeWord, 
        new Vector2(
            this.Window.ClientBounds.Width / 2,
            this.Window.ClientBounds.Height - 25), 
        Color.Green);
    
    spriteBatch.DrawString(
        letterFont, 
        currentLetter, 
        new Vector2(
            this.Window.ClientBounds.Width / 2 +   
                letterFont.MeasureString(beforeWord).X,
            this.Window.ClientBounds.Height - 25), 
        Color.Yellow);
    
    spriteBatch.DrawString(
        letterFont, 
        afterWord, 
        new Vector2(
          this.Window.ClientBounds.Width / 2 + 
             letterFont.MeasureString(beforeWord+currentLetterIndex).X,
          this.Window.ClientBounds.Height - 25), 
        Color.LightBlue);
    
    spriteBatch.DrawString(
        letterFont, 
        "Score: " + playerScore.ToString(), 
        Vector2.Zero, 
        Color.White);
    
    spriteBatch.End();

What just happened?

When using the SpriteBatch class, any calls to draw graphics or text must be wrapped in calls to Begin() and End(). SpriteBatch.Begin() prepares the rendering system for drawing 2D graphics and sets up a specialized render state. This is necessary because all 2D graphics in XNA are actually drawn in 3D, with the projection and orientation configurations in the render state to display the 2D images properly.

In our case, the only graphical image we are drawing is the square that represents the player. We draw this with a simple call to SpriteBatch.Draw(), which requires the texture we will use, the location where the texture will be drawn on the screen (relative to the upper-left corner of the display area), and a tint color. Because our square image is white, we could set any color we wish here and the player's square would take on that color when displayed. We will use that to our advantage in just a moment when we draw the text of the word the player is trying to spell.

After the player has been drawn, we loop through each of the letters in the letters list and use the SpriteBatch.DrawString() method to draw the letter at its position, using the letterFont we created earlier. Normally, we will draw the letters in white, but if the player runs into this letter (and it is not the letter they are supposed to hit) we will draw it in red.

Next, we need to display the word that the player is attempting to spell. We display the text Spell: near the bottom center of the display, using the bounds of the current window to determine the location to draw.

In order to colorize the word properly, we need to split the word into different parts as what the player has already spelled, the current letter they are targeting, and the letters after the current letter. We do this using the Substring() method of the string class, and then draw these three components with different color tints. We utilize the MeasureString() method of letterFont to determine how much space each of these components occupies on the screen so that we can position the subsequent strings properly.

Finally, we display the player's score at the upper-left corner of the screen.

Helper methods


All that remains to finish the Speller game is to create our two missing methods, CheckForNewWord() and CheckCollisions(). We will actually break these down into other helper functions as well.

Time for action – words and letters


To implement the CheckForNewWord() and its helper methods, we will perform the following steps:

  1. 1. Add the PickAWord() method to the end of the Game1 class, after Draw():

    private string PickAWord()
    {
        switch (rand.Next(15))
        {
            case 0: return "CAT"; 
            case 1: return "DOG"; 
            case 2: return "MILK";
            case 3: return "SUN";
            case 4: return "SKY";
            case 5: return "RAIN";
            case 6: return "SNOW";
            case 7: return "FAR";
            case 8: return "NEAR";
            case 9: return "FRIEND";
            case 10: return "GAME";
            case 11: return "XNA";
            case 12: return "PLAY";
            case 13: return "RUN";
            case 14: return "FUN";
        }
    
        return "BUG";
    }
  2. 2. Add the FillLetters() method to the Game1 class, after PickAWord():

    private void FillLetters(string word)
    {
      Rectangle safeArea = new Rectangle(
        this.Window.ClientBounds.Width / 2 - playerSquare.Width,
        this.Window.ClientBounds.Height / 2 - playerSquare.Height,
        playerSquare.Width * 2,
        playerSquare.Height * 2);
    
      string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
      List<Vector2> locations = new List<Vector2>();
      for (int x=25;x < this.Window.ClientBounds.Width - 50;x += 50)
      {
        for (int y=25;y < this.Window.ClientBounds.Height - 50;y += 50)
        {
          Rectangle locationRect = new Rectangle(
            x,
            y,
            (int)letterFont.MeasureString("W").X,
            (int)letterFont.MeasureString("W").Y);
    
          if (!safeArea.Intersects(locationRect))
          {
            locations.Add(new Vector2(x, y));
          }
        }
      }
    
      letters.Clear();
      for (int x = 0; x < 20; x++)
      {
        GameLetter thisLetter = new GameLetter();
    
        if (x < word.Length)
            thisLetter.Letter = word.Substring(x, 1);
        else
            thisLetter.Letter = alphabet.Substring(
                rand.Next(0,26),1);
    
            int location = rand.Next(0,locations.Count);
            thisLetter.Position = locations[location];
            thisLetter.WasHit = false;
            locations.RemoveAt(location);
      
            letters.Add(thisLetter);
        }
    
    }
  3. 3. Add the CheckForNewWord() method to the end of the Game1 class, after FillLetters():

    private void CheckForNewWord()
    {
        if (currentLetterIndex >= currentWord.Length)
        {
            playerPosition = new Vector2(
                this.Window.ClientBounds.Width / 2,
                this.Window.ClientBounds.Height / 2);
            currentWord = PickAWord();
            currentLetterIndex = 0;
            FillLetters(currentWord);
        }
    }

What just happened?

In step 1, we generate a random number using the Next() method of the Random class. Given an integer value, Next() will return an integer between zero and that number minus one, meaning we will have a return value from zero to fourteen. Using a select statement, we return the randomly determined word. Note that we should never hit the last return statement in the function, so if we are ever asked to spell the word BUG, we know something is wrong.

The FillLetters() method is used to populate the letters list with letters and their locations on the screen. We could simply generate random locations for each letter, but then this would leave us with the potential for letters overlapping each other, requiring a check as each letter is generated to ensure this does not happen.

Instead, we will generate a list of potential letter positions by building the locations list. This list will contain each of the possible places on the screen where we will put a letter by spacing through a grid and adding entries every 25 pixels in the x and y directions. The exception is that we define an area in the center of the screen where the player will start and we will not place letters. This allows the player to start each round without being in contact with any of the game letters.

Once we have our list of locations, we clear the letters list and generate 20 letters. We start with the letters required to spell the target word, pulling letters from the currentWord string until we reach the end. After that, the letters will come from the alphabet string randomly. Each letter is assigned one of the locations from the locations list, and that location is then removed from the list so we will not have two letters on top of each other.

Lastly, the CheckForNewWord() method checks to see if currentLetterIndex is larger than the length of currentWord. If it is, the player's position is reset to the center of the screen and a new word is generated using PickAWord(). currentLetterIndex is reset, and the letters list is rebuilt using the FillLetters() method.

Time for action – completing the Speller project


To complete the Speller project we need to add the CheckCollosions() method by performing the following steps:

  1. 1. Add the CheckCollisions() method to the Game1 class after CheckForNewWord():

    private void CheckCollisions()
    {
        for (int x = letters.Count - 1; x >= 0; x--)
        {
            if (new Rectangle(
                (int)letters[x].Position.X,
                (int)letters[x].Position.Y,
                (int)letterFont.MeasureString(
                    letters[x].Letter).X,
                (int)letterFont.MeasureString(
                    letters[x].Letter).Y).Intersects(
                        new Rectangle(
                            (int)playerPosition.X,
                            (int)playerPosition.Y,
                            playerSquare.Width,
                            playerSquare.Height)))
            {
               if (letters[x].Letter == 
                   currentWord.Substring(currentLetterIndex, 1))
               {
                   playerScore += 1;
                   letters.RemoveAt(x);
                   currentLetterIndex++;
               }
               else
               {
                   if (!letters[x].WasHit)
                   {
                       playerScore -= 1;
                       letters[x].WasHit = true;
                   }
               }
            }
            else
            {
                letters[x].WasHit = false;
            }
        }
    }
  2. 2. Execute the Speller project and play! The following screenshot shows how our game will look when we execute it:

What just happened?

CheckCollisions() loops backward through the letters list, looking for letters that the player has collided with. Going backwards is necessary because we will (potentially) be removing items from the list, which cannot be done in a foreach loop. If we were moving forward through the list, we would disrupt our loop by deleting the current item, which would cause it to skip over the next items in the list. Moving backwards through the list allows us to remove items without adjusting our loop's logic.

In order to determine if we have collided with a letter, we build two rectangles. The first rectangle represents the position and size of the letter we are checking against, by using the letter's Position value and the size of the letter calculated with MeasureString(). The second rectangle represents the area occupied by the player's sprite.

The Intersects() method of the Rectangle class will return true if these two rectangles overlap at any point. If they do, we know we have hit a letter and need to take action.

If the letter impacted is the next letter in the word that the player is spelling, we increment the player's score and remove the letter from the list. We also advance currentLetterIndex so that when Update() next calls CheckForNewWord(), we will know if this word has been completed.

If the letter is not the player's current target, we check the letter's WasHit value. If it is false, we have not run into this letter, so we reduce the player's score and mark WasHit to true. If WasHit is already true, we simply do nothing so as not to deduct from the player's score multiple times while the player passes over an incorrect letter.

When the rectangles do not intersect, we know we are not currently in contact with this letter, so we set its WasHit variable to false. This has the effect that once we leave an incorrect letter, it becomes re-enabled for future collisions (and point deductions).

Have a go hero

Speller is a pretty simple game, but could be enhanced to make a more full-fledged game, by including the following, depending on your level of experience with 2D XNA development:

  • Beginner: Raise the difficulty by increasing the speed of the player's square as they complete each word.

  • Intermediate: Record the words with a microphone and play those recordings when a new word is generated. Instead of displaying the entire word during the update() method, display only the letters that have been spelled so far. This would turn the game into more of an educational kid's game with the player having to spell out the words they hear.

Summary


As a quick-fire introduction to a number of essential XNA topics, Speller covers quite a bit of ground. We have a functional game that accepts player input, draws graphics and text to the screen, generates a random playfield of letters, and detects player collision with them. We got an overview of the structure of an XNA game and the basic Update()/Draw() game loop.

As we will see, many of these concepts translate into a 3D environment with very little need for modification, other than the need to keep track of positions and movement with an extra dimension attached. We will utilize the Vector3 objects instead of the Vector2 objects, and we will still rely on a 2D plane for much of the layout of our game world.

Additionally, although much of the work in the following chapters will take place with 3D drawing commands and constructs, we will still be returning to the 2D SpriteBatch and SpriteFont classes to construct interface elements and convey textual information to the player.

Left arrow icon Right arrow icon

Key benefits

  • Learn the structure of a 3D world and how to implement a variety of 3D techniques including terrain generation and 3D model rendering.
  • Build three different types of 3D games step-by-step, including a first-person maze game, a battlefield tank game, and a 3D sidescrolling action game on the surface of Mars.
  • Learn to utilize High Level Shader Language (HLSL) to add lighting and multi-texturing effects to your 3D scenes.

Description

Move beyond the world of flat 2D-based game development and discover how to create your own exciting 3D games with Microsoft XNA 4.0. Create a 3D maze, fire shells at enemy tanks, and drive a rover on the surface of Mars while being attacked by alien saucers."XNA 4 3D Game Development by Example: Beginner's Guide" takes you step-by-step through the creation of three different 3D video games with Microsoft XNA 4.0. Learn by doing as you explore the worlds of 3D graphics and game design.This book takes a step-by-step approach to building 3D games with Microsoft XNA, describing each section of code in depth and explaining the topics and concepts covered in detail. From the basics of a 3D camera system to an introduction to writing DirectX shader code, the games in this book cover a wide variety of both 3D graphics and game design topics. Generate random mazes, load and animate 3D models, create particle-based explosions, and combine 2D and 3D techniques to build a user interface."XNA 4 3D Game Development by Example: Beginner's Guide" will give you the knowledge to bring your own 3D game creations to life.

Who is this book for?

This book is intended for readers who want to create 3D games using the XNA Framework. Basic knowledge of the C# programming language and 2D XNA concepts are helpful, but not required.

What you will learn

  • The core concepts of 3D graphics and how XNA describes the 3D world
  • Build a 3D maze that the player can explore in search of the mysterious spinning cube
  • Create 3D terrain based on a 2D height map image, adding texturing and lighting to the terrain s surface
  • Load, display and animate 3D models
  • Build a button-based user interface overlay for your 3D game
  • Create a billboard particle system to produce dynamic explosions
  • Build a skybox to give your worlds full 3D backgrounds
  • Detect collisions between 3D objects and have your game react accordingly

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Sep 25, 2012
Length: 322 pages
Edition : 1st
Language : English
ISBN-13 : 9781849687089
Vendor :
Microsoft
Languages :

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing

Product Details

Publication date : Sep 25, 2012
Length: 322 pages
Edition : 1st
Language : English
ISBN-13 : 9781849687089
Vendor :
Microsoft
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 121.97
XNA 4.0 Game Development by Example: Beginner's Guide
€37.99
Microsoft XNA 4.0 Game Development Cookbook
€41.99
XNA 4 3D Game Development by Example: Beginner's Guide
€41.99
Total 121.97 Stars icon
Banner background image

Table of Contents

10 Chapters
Introduction to XNA Chevron down icon Chevron up icon
Cube Chaser – A Flat 3D World Chevron down icon Chevron up icon
Cube Chaser – It's A-Mazing! Chevron down icon Chevron up icon
Cube Chaser – Finding Your Way Chevron down icon Chevron up icon
Tank Battles – A War-torn Land Chevron down icon Chevron up icon
Tank Battles – The Big Guns Chevron down icon Chevron up icon
Tank Battles – Shooting Things Chevron down icon Chevron up icon
Tank Battles – Ending the War Chevron down icon Chevron up icon
Mars Runner Chevron down icon Chevron up icon
Mars Runner – Reaching the Finish Line Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.1
(7 Ratings)
5 star 42.9%
4 star 42.9%
3 star 0%
2 star 14.3%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




jp sousa Jun 12, 2013
Full star icon Full star icon Full star icon Full star icon Full star icon 5
First I should say that I AM skilled in 2D animations using Silverlight but have never used XNA. I HAVE done a little Silverlight 3D programming and mainly I wanted to improve my Silverlight 3D animations skills.I followed through the entire book by initiating my own Projects. I did not, however, type in all the code. Instead, I just copied the regions one by one for each class file, making only minimal effort to understand each region. All the while I thought that my laziness would jump up and bite me. But, after I finished, I was surprised to find out that I was able to easily add sound to the Tank Battles game and to add explosions to the Mars Runner game. I think the author succeeded wonderfully in progressing his readers through many levels of XNA programming. I also liked the way he made most of the classes generic so that they will be usable in my own projects.
Amazon Verified review Amazon
M. Loretti Dec 11, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I have recently bought two books about game development with Microsoft XNA Framework from Packt Publishing, one of them being "XNA 4 3D Game Development". Both of them are written by the same author (Kurt Jaegers) and are a great read for beginner game developers.I come from a web development background where I work with both front and back-end technologies. Before reading this book I had almost no experience with C# and none with XNA or game development in general. Author does a great job throughout the book at explaining all the basic concepts about game development, including C#, how XNA works and basic game theories.First chapter is introductory chapter about programming with XNA and it walks you through creating a very simple 2D game - yes, a 2D game because a lot of basics about 3D game programming come from the 2D world. The rest of the book is about 3D games and increase in difficulty building upon the concepts that you have learned in previous chapters.I really enjoyed reading XNA book series by Kurt Jaegers because his writing style is extremely easy to read and he does a great job at explaining all the concepts to the reader, even though the book itself is written in "learn by doing" style. This book assumes that you know a little bit about programming already, however it does give you a quick 101 about C#. I am really happy with my purchase and recommend this book to anyone who wants to learn about basic 3D game programming with Microsoft XNA Framework.
Amazon Verified review Amazon
Michael Liddy Dec 27, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I am completely new to 3D, C# and .NET but at one stage in my career I was a programmer so I understand programming concepts.With this context the book really worked for me. It might be a stretch for a complete beginner but anyone with rudimentary programming skills that learns by example and doing, rather than text book theory should really get a lot out of this.The code examples are easy to follow and the fact that they are in a real, even if a little simple, game situation really made it easy for me to follow.Against a couple of other more detailed and comprehensive XNA books that I purchased at the same time, this is the one that got me the furthest in the shortest time.Seeing progress 'on screen' almost immediately really helped me keep motivated to keep working through the book.I thoroughly enjoyed it.
Amazon Verified review Amazon
Wessam Bahnassi Dec 17, 2012
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
The book comes in two flavors, C# and Visual Basic (there is also a 3D vs. non-3D edition, this is the 3D edition, watch the title). I have read the C# edition from cover to cover assuming that I'm a new comer to programming and games altogether.Overall, it's a good read, and I think a considerable number of readers will like the way it presents information. A good book offers what it promises in its title, and that is the case with this beginner's guide. Four example games are used as a vehicle to demonstrate basic game functionality such as world updates, user input, box collision detection, generating simple geometry and 2D drawing. It also touches on a few more complicated tasks such as terrain generation and lighting, skeletal hierarchies and particle effects.It is difficult to say for certain, especially that different people learn in different way; this book sticks really to the "by example" clause. Each chapter starts by telling you what you are going to achieve, then displays code snippets followed by a "What just happened?" section that explains the rationale behind the code. Personally, this is opposite to how I would like to receive new knowledge. I'm a guy who likes to know the story behind so I can come up by my self with the conclusion of what should be done, and I do not know how many people agree with me on this.The book does not say much about what knowledge is required from the reader so he can use the book. After reading it, I can say it assumes basic knowledge of C# (there is no focus at all on teaching the programming language, which is just fair in my opinion). It avoids using advanced C# code constructs, so having read a C# primer before this book should be sufficient.When talking about games (especially 3D games), you are faced with the challenge of using terms that would take a long time to explain the story for each of them (e.g., normals, textures, matrices, vertex/index buffers, HLSL). The author makes an attempt to explain the term when using it the first time, but I find the explanations too brief and leave much to be desired. Giving a reference for further exploration could have helped a bit here. Without such understanding it would be difficult to be able to innovate something beyond what is given in the examples. Some books show on the back cover the level you will reach after reading them. In our case I think this book takes you from Beginner 0 to Beginner 2. Not much beyond.To wrap up, from my perspective, Kurt Jaegers' XNA Beginners' Guide is a useful read, with nice and clever games used as driving examples. It helps the reader break the hard startup barrier and opens his appetite for wider and deeper knowledge on the various facets of game programming with XNA.
Amazon Verified review Amazon
RB Nov 20, 2012
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This is a very good book!I've read several books on developing XNA games (and even some websites) but none give such a straightforward presentation to games development.I have been waiting for a book that just gets to the "meat" of the issue and Kurt Jaegers' book does just that.Highly recommended for those who want to dive right into to games development.FYI, if you read this book on Kindle, be aware that Kindle might hyphenate some of the code blocks, making it appear there are minus-signs in the code when there should not be. I had a couple of bugs because of this; I recommend widening or rotating the page view to see if the code block changes.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is included in a Packt subscription? Chevron down icon Chevron up icon

A subscription provides you with full access to view all Packt and licnesed content online, this includes exclusive access to Early Access titles. Depending on the tier chosen you can also earn credits and discounts to use for owning content

How can I cancel my subscription? Chevron down icon Chevron up icon

To cancel your subscription with us simply go to the account page - found in the top right of the page or at https://subscription.packtpub.com/my-account/subscription - From here you will see the ‘cancel subscription’ button in the grey box with your subscription information in.

What are credits? Chevron down icon Chevron up icon

Credits can be earned from reading 40 section of any title within the payment cycle - a month starting from the day of subscription payment. You also earn a Credit every month if you subscribe to our annual or 18 month plans. Credits can be used to buy books DRM free, the same way that you would pay for a book. Your credits can be found in the subscription homepage - subscription.packtpub.com - clicking on ‘the my’ library dropdown and selecting ‘credits’.

What happens if an Early Access Course is cancelled? Chevron down icon Chevron up icon

Projects are rarely cancelled, but sometimes it's unavoidable. If an Early Access course is cancelled or excessively delayed, you can exchange your purchase for another course. For further details, please contact us here.

Where can I send feedback about an Early Access title? Chevron down icon Chevron up icon

If you have any feedback about the product you're reading, or Early Access in general, then please fill out a contact form here and we'll make sure the feedback gets to the right team. 

Can I download the code files for Early Access titles? Chevron down icon Chevron up icon

We try to ensure that all books in Early Access have code available to use, download, and fork on GitHub. This helps us be more agile in the development of the book, and helps keep the often changing code base of new versions and new technologies as up to date as possible. Unfortunately, however, there will be rare cases when it is not possible for us to have downloadable code samples available until publication.

When we publish the book, the code files will also be available to download from the Packt website.

How accurate is the publication date? Chevron down icon Chevron up icon

The publication date is as accurate as we can be at any point in the project. Unfortunately, delays can happen. Often those delays are out of our control, such as changes to the technology code base or delays in the tech release. We do our best to give you an accurate estimate of the publication date at any given time, and as more chapters are delivered, the more accurate the delivery date will become.

How will I know when new chapters are ready? Chevron down icon Chevron up icon

We'll let you know every time there has been an update to a course that you've bought in Early Access. You'll get an email to let you know there has been a new chapter, or a change to a previous chapter. The new chapters are automatically added to your account, so you can also check back there any time you're ready and download or read them online.

I am a Packt subscriber, do I get Early Access? Chevron down icon Chevron up icon

Yes, all Early Access content is fully available through your subscription. You will need to have a paid for or active trial subscription in order to access all titles.

How is Early Access delivered? Chevron down icon Chevron up icon

Early Access is currently only available as a PDF or through our online reader. As we make changes or add new chapters, the files in your Packt account will be updated so you can download them again or view them online immediately.

How do I buy Early Access content? Chevron down icon Chevron up icon

Early Access is a way of us getting our content to you quicker, but the method of buying the Early Access course is still the same. Just find the course you want to buy, go through the check-out steps, and you’ll get a confirmation email from us with information and a link to the relevant Early Access courses.

What is Early Access? Chevron down icon Chevron up icon

Keeping up to date with the latest technology is difficult; new versions, new frameworks, new techniques. This feature gives you a head-start to our content, as it's being created. With Early Access you'll receive each chapter as it's written, and get regular updates throughout the product's development, as well as the final course as soon as it's ready.We created Early Access as a means of giving you the information you need, as soon as it's available. As we go through the process of developing a course, 99% of it can be ready but we can't publish until that last 1% falls in to place. Early Access helps to unlock the potential of our content early, to help you start your learning when you need it most. You not only get access to every chapter as it's delivered, edited, and updated, but you'll also get the finalized, DRM-free product to download in any format you want when it's published. As a member of Packt, you'll also be eligible for our exclusive offers, including a free course every day, and discounts on new and popular titles.