Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating a 3D Space Invaders Game From Scratch in XNA

0.00/5 (No votes)
21 Sep 2008 1  
A series of articles meant to build a 3D space invaders game from the ground up using Microsoft's XNA technology.

Introduction

Just getting started with game programming? Itchy to make your own game?

This is the first article in a series that will teach you how to put together a 3D Space Invaders-like game, completely from scratch, using Microsoft's XNA game programming framework.

Background

About 10 years ago, game programming piqued my teenage interest. I bought some books on DirectX and C++ programming, and dove in head-first. Unfortunately, as I soon found out, going from zero programming knowledge to straight game programming with C++ and DirectX is like trying to understand calculus before learning to add and subtract.

Frustrated, I learned other programming languages, and turned to some higher level game engines. I found one web-based game engine called WildTangent WebDriver, that had a beautifully simple "How to make a game" tutorial. It led you step-by-step through creating a 3D space invaders game using the WebDriver game engine. As someone new to programming, it was precisely what I needed. It helped me so much, I ended up creating a C++ enhanced version of the tutorial, learned the whole damn thing inside and out, and became an avid fan of the game engine.

Fast-forward to today, the WildTangent WebDriver game engine is gone (though the company still exists), but my passion for learning game programming still exists.

This series of articles is an attempt to recreate that tutorial using Microsoft's XNA programming framework. I hope to capture the simplicity of that original tutorial and show you how to create a 3D game using the XNA game programming framework and the C# programming language.

All that said, I'm a game programming newbie by all means! I've little experience with raw DirectX and XNA. Today, I'm a business software developer, not a game developer, so this is a learning experience for me too! I hope these articles will help you out just as much as I learn from the experience. (XNA experts, please tell me where my code smells, please criticize and tell me what I'm doing wrong.)

Also, this is my first article. Let me know how I did in the comments.

Who should be reading this?

Newbie game programmers who are interested in making 3D computer games!

To understand this series of articles, I recommend you have some basic knowledge of the C# programming language, but none is really required.

We will be using Microsoft's XNA game programming framework to make this game, so even C# gurus will be seeing this stuff for the first time.

What you need

Overview

In this first part of the series, we'll build the basics -- drawing things to the screen, loading models, moving around with the keyboard. By the end of this article, you won't be playing Space Invaders (yet), but you will have the basics in place that will let you move around a level with your keyboard.

In the next article, we'll build on these basics, and you'll start shooting aliens in no time.

Ready? Let's dig in.

Code overview

For this series of articles, we'll be using a simple game engine I built on top of XNA, called Arlandria. We'll use it in our 3D Space Invaders game.

What is a game engine, you ask? A game engine is an abstraction, a layer on top of the underlying code that makes it easier to write games. So, instead of writing:

// Without game engine abstraction... :-(
computerPlayer.Mesh[0].Effect.World *= Matrix.CreateTranslation(spawnLocation); 

You get this nice, easy to read piece of code:

// With game engine... :-)
computerPlayer.Position = spawnLocation; 

The idea is to hide some of the complexity, letting us focus on making games. OK? We'll be using the Arlandria game engine so that we can just write gun.Shoot() or alien.Position = earth. Then, we'll use that to make our actual 3D Space Invaders game.

Brief description of the Arlandria game engine

Our simple game engine is pretty easy to get your head around. There are only four objects in it:

  • Scene - This is our world, our stage. Holds all the objects in the game.
  • Group - This is something that just holds other objects. Think of it like an invisible box you can put other things in.
  • Model - A type of Group that holds a 3D model loaded from a file.
  • Camera - Exactly what you think: the seeing-eye that looks at our world and shows the beautiful imagery to your screen.

I wrote these objects to hide some of the complex parts of dealing directly with the XNA game programming framework. We won't go into the code of these objects in this article, but feel free to investigate and see how they work, they're included in the source code. In a future article, we'll discuss the more complex details of dealing directly with the XNA engine and how transformations like movement and rotation work.

3D Space Invaders code

Our first order of business is to make the things we'll be using in our game. Today, we'll need our world, which we'll call scene, and we'll need the camera to view the world.

// Keep our scene and our camera around. We'll need them later.
Scene scene;
Camera camera;

/// <summary>
/// Creates a new SpaceInvaders3d object.
/// </summary>
public SpaceInvaders3d()
{
   // Before we can create our scene, we'll need
   // some XNA objects to do some house-keeping.
   GraphicsDeviceManager graphics = new GraphicsDeviceManager(this);
   ContentManager contentManager = new ContentManager(base.Services);
 
   // Now that we have those XNA house-keeping objects,
   // we can create our scene!
   scene = new Scene(graphics, contentManager);
   scene.BackColor = Color.CornflowerBlue;
}


/// <summary>
/// Called by XNA when the game's content (models, audio, textures, etc.)
/// is ready to load.
/// 
/// The purpose is to create our camera.
/// </summary>
/// <param name="loadAllContent">Which type of content to load.</param>
protected override void LoadGraphicsContent(bool loadAllContent)
{
    if (loadAllContent)
    {
        // Create a camera a little ways back from the center of the screen.
        camera = new Camera();
        camera.Position = new Vector3(0, 0, 300);
    }
}

There, we have our world! If you stop and run it now, you'll see it's completely Cornflower Blue! And empty.

SpaceInvadersEmpty.gif

That wasn't so hard. The XNA house-keeping stuff helps us manage our content (models, textures, etc.) and manage our graphics surface (the screen that we're drawing to). Don't worry about those for now, we just need to create them, and the scene will take care of it from here out.

OK, so far, we've got our world, but it's pretty boring -- all we have is an empty blue world! Let's fix that. We're going to load a 3D model of a room with four corners and some fantastic abstract art hanging on the walls. I created this model using a cheap ($30 USD) 3D modeling tool called Milkshape3d, but you can create models using any tool that exports to the .FBX file format.

Once you've got your .FBX model file, you add it to your game via the XNA Game Studio tool. Simply right-click on your game project, Add Existing Item..., and select your file.

SpaceInvadersAddingContent.png

Now, we've got our 3D model inside our project, we can load it through code. Right after we create our camera, add these two lines:

// Create our room. It's got 4 walls with some fancy abstract art on it.
Model room = new Model("Content\\Models\\room");
scene.Children.Add(room);

Piece of cake! Now, we really have something!

SpaceInvadersLevel.png

Great! Now, we have some pretty things to look at. But, it's not exactly action-packed alien destruction, yet.

Let's make it so the player can move around when you press keys on the keyboard. Standard fare for a first-person shooter is the W, A, S, D set of keys for movement (W = forward, S = backward, A = left, D = right). Let's build that now.

With XNA, you update your game state (like player movement) inside a special function called Update. Here's what it looks like:

/// <summary> 
/// Allows the game to run logic such as updating the world, 
/// checking for collisions, gathering input and playing audio. 
/// </summary> 
/// <param name="gameTime">Provides a snapshot of timing values.</param> 
protected override void Update(GameTime gameTime)
{
    base.Update(gameTime);
}

Inside of that special function, let's check if the user pressed the W, A, S, or D keys and move the camera accordingly. Inside that function, just above the base.Update(gameTime); line, add the line ProcessKeyPresses();

Then, we'll code up the ProcessKeyPresses function like so:

///<summary> 
/// Checks the state of the keyboard and moves the camera as necessary. 
/// </summary> 
private void ProcessKeyPresses()
{
    // Standard first-person shooter keys. 
    const Keys moveLeftKey = Keys.A;
    const Keys moveRightKey = Keys.D;
    const Keys moveForwardKey = Keys.W;
    const Keys moveBackwardKey = Keys.S;
 
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(moveForwardKey))
    {
        this.camera.Position += Vector3.Forward;
    }
    else if (keyState.IsKeyDown(moveBackwardKey))
    {
        this.camera.Position += Vector3.Backward;
    }
    else if (keyState.IsKeyDown(moveLeftKey))
    {
        this.camera.Position += Vector3.Left;
    }
    else if (keyState.IsKeyDown(moveRightKey))
    {
        this.camera.Position += Vector3.Right;
    }
}

Pretty simple code: all we're doing here is just adjusting the camera's position based on what keys were pressed.

End result? We can move the camera around with the keyboard! Woo! That lets us get a close up on that fine art hanging on the wall...

SpaceInvadersMoving.png

OK, so now, we can load up 3D models and move our camera around our cornflower-lovin' world using the W, A, S, D keys. Things are taking shape!

In part 2, we'll look at how to move the player's view around with the mouse, first-person shooter style. We'll also be armed...and dangerous! Stay tuned.

Acknowledgments

Many thanks to Mark Lamprecht, Brent Orford, Ryan Rogers, Todd Zircher, and all the Genesis3d and WildTangent folks who put up with my newbie questions and helped me start out on my programming journey. Especially, thanks to Mark who created the WildTangent tutorial game on which this series of articles is based.

History

  • 7-07-08 - First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here