The intelligence of machines and the branch of computer science which aims to create it

Artificial Intelligence Journal

Subscribe to Artificial Intelligence Journal: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get Artificial Intelligence Journal: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn

Artificial Intelligence Authors: William Schmarzo, Stackify Blog, Pat Romanski, Liz McMillan, Progress Blog

Related Topics: Artificial Intelligence Journal, Game Developer

Artificial Intelligence: Article

XNA, Game Development for Everyone

Writing games sure isn't what it used to be

If you try to run the current project you'll see a cornflower-blue window of 800x600 pixels pop up and that's all, but if you set breakpoints for all of the functions I mentioned you'll see that the XNA Framework's logic flow works something like this:

  1. The main application calls the Game Constructor.
  2. The XNA Framework calls the game's Initialize method.
  3. The XNA Framework calls the game's LoadContent method.
  4. The XNA Framework calls the game's Update method.
  5. The XNA Framework calls the game's Draw method.
  6. Steps 4 and 5 are repeated many times each second.
  7. If the application closes then a call is made to UnloadContent.

We can clearly see that the game loop exists and that the update and draw methods are the places for our game logic and graphics drawing.
Bringing Something Up on the Screen

If you're not already excited about game programming maybe you will be as soon as you see more than a blue background screen. To get started we need to create or import a few images (see Figure 3):

  • The actual track - I borrowed the track and took screenshots from the existing VW Lupo Cup game for this article.
  • An image of any size with a black background and another one with a silver background (these can be easily done in your preferred painting program).
  • An image of a nice car that you'd like to drive around.

If you don't want to create these on your own, feel free to download the source code for this article, which includes all of the images used.

We have to import these images into the project's content subfolder (another new feature of the XNA Framework 2.0) where all the content files should be. Your Solution Explorer should look like the one in Figure 4.

The next step is to show the background and a scoreboard to display the player's name and current and best lap time. To do this we start by defining some instance variables that will hold our textures of the track and scoreboard - where we also need two rectangles that define the size of the scoreboard and its border:

Texture2D scoreBoard;
Texture2D scoreBorder;
Texture2D track;
Rectangle scoreRect = new Rectangle(50, 450, 120, 70);
Rectangle scoreRectAround = new Rectangle(45, 445, 130, 80);

The next step is to code the LoadContent function and load the images. We use an image with a black background for the scoreboard and surround it with a gray border to make it look nicer not forgetting our real background, the track itself. We do this simply by telling the 'Content Pipeline' to load our textures (from the Content subdirectory). The XNA content pipeline is used to load 3D objects (that you've exported from Blender or 3DStudio), textures (this is exactly what we want to do), effects (light, bump mapping), or Microsoft Cross-Platform Audio Creation Tool (XACT) projects. This kind of different content can be created with many different tools and saved in many different file formats. Using the content pipeline built to import most of the common file formats, this content is processed automatically into a managed code object that can be loaded and used by XNA Game Studio games on Windows and the Xbox 360 at runtime (all our content files are compiled into .xnb files and our audio files are compiled into .xgs, .xwb, and .xsb files for the actual sound project, wave bank, and sound bank content).

// TODO: use this.Content to load your game content here
scoreBoard = Content.Load<Texture2D>("Black");
scoreBorder = Content.Load<Texture2D>("Grey");
track = Content.Load<Texture2D>("Track");

Now before we test our cool game we code the draw function, where we simply draw the track, the border, and the actual scoreboard - in that order - so that everything appears on the screen. This is done in a sprite batch because by using it we send a single draw call to the graphics card.

If we did it without using a sprite batch we'd put a load on the gaming machine that would slow things down and maybe result in an unplayable game since all the drawing commands are sent separately to the graphics card every time we draw something to the screen - and that's the last thing we want.

// TODO: Add your drawing code here
spriteBatch.Draw(track, new Rectangle(0, 0, track.Width, track.Height), Color.White);
spriteBatch.Draw(scoreBorder, scoreRectAround, Color.White);
spriteBatch.Draw(scoreBoard, scoreRect, Color.White);

Note that we haven't coded anything in the update function so far because we don't have any game logic yet. If we run the application we see nearly the same thing as in Figure 1 - only the cars are missing and there's no text on our scoreboard. Fine, but what's a racing game without any players? OK, let's create the cars and put them on the starting line.

The first object we should create now is a player class. It's always good to have a class with the player-specific values. You might think that's unnecessary, but it's not. The more you work on a game the more features you want to build into the application. For example, in the beginning you might only have a player name and the laps driven, as well as the current position (x, y coordinates and rotation) of the car. Later on you might want to keep the track record and current points if you stage some kind of championship season, or - even simpler - the keyboard should be configurable, and so on. You can see my current player class in Listing 1 (I'm quite sure that this will be far bigger by the time you read this article).

More Stories By Berndt Hamboeck

Berndt Hamboeck is a senior consultant for BHITCON ( He's a CSI, SCAPC8, EASAC, SCJP2, and started his Sybase development using PB5. You can reach him under [email protected]

Comments (4) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

Most Recent Comments
DavidM 05/06/08 09:41:19 PM EDT

How can I contact the author?

What the heck

DavidM 05/06/08 09:40:33 PM EDT

When did .NETDJ go digital?

This site is so confusing.

Where the heck do I go to download the source for this article?

SYSCON needs to re-do this junk and provide the readers with an easy way to navigate the site, find the magazine in question, and find the code that goes with it!

Where is the second article to this? I see the next month appeared but no mention of XNA??

tori 04/03/08 10:31:31 PM EDT

This is very confusing to me, I just started using XNA and thought that this would be helpful and so far this article has only confused me. There is no downloadable source code and there is not enough description of the steps. This looked interesting, but in the end was disappointing.

Oscar Peli 03/28/08 12:26:15 PM EDT

Where can I download the source code for this article?