Ok, this is the first XNA tutorial in a series, that will demonstrate how to create a complete game from scratch. I would recommend you don't copy and paste source code from this, at least not at first, make sure you understand it, or you won't have picked anything up. First though, you'll need some tools.
What you need:
Visual C# Express 2005
XNA 2.0
Both of which can be found here:
http://creators.xna.com/Resources/Essentials.aspxNote:
Visual C# Express might want a patch, that can be found with a google search.
If you have an old computer you might not be able to run XNA applications. It needs at least pixel shader 2.0 support, last I heard.
Once you've done all the restarting, patching and such, you should have a shortcut somewhere in your start bar saying “XNA Game Studio Express. Click this.
I would strongly suggest at this point that if you haven't looked at C# or any programming before, you do so before you continue, unless you are really desperate to make a game right now.
Anything like tutorials from
http://csharpcomputing.com/Tutorials/TOC.htm will do, or if you want a book I recommend this
http://www.amazon.co.uk/Programming-Key-As...04739385&sr=8-1.
So if you're still with me, go to File-> New Project. You'll see here there are a lot of options, these don't matter for now, click 'XNA Tutorial Game', give it a sensible name like “XNA Tutorial 1” and click Ok.
When it loads you'll be welcomed by what we've affectionately nicknamed 'The Green Sea'. What you see there are the core functions of the XNA framework, added to make your life easier. The names and essay-like comments should explain quite well what they do. Give it a quick read.
If you look at the interface, at the top you should see a green button that looks like a play button. If you press this the game will begin debugging, which you can use later to look for errors, and also test your program. This can also be used by pressing F5 on your keyboard. If you hit F5 now, you should be hit with a screen like this:

This is the standard Cornflower Blue, clear colour. The clear colour is what any real time rendering application fills the frame with before each frame is rendered. It doesn't look like it's moving, but it's probably redrawing as much as 700 times per second, depending on your system specification.
From what I saw of tutorials, very few, possibly none ever cover the actual game development part, and write all of their tutorial code to use one class. As good as this is for demonstration, it has no really practical application. So the first thing we're going to do is break it down, and abstract all of our code away from the green sea, but first, right click this file in the solution explorer, 'Game1.cs', and rename it 'Pipeline.cs'.
Right click on 'XNA Tutorial Game' in the solution explorer, it should be in Bold, click Add->Class.., call it Game, and click Ok.
The first thing to do is copy the using statements from the first file into this one, so all of this:
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
You can get rid of the other ones that were there if you like, they won't make any difference. So now you have your game class, you need to conisder what it is that a game does. Well, the starter file helps you out here a little and gives you a few clues. It must Initialise, Load Content, Update and Render as a minimum. These are the only things we need it to do for the moment. So create these functions in the Game class:
| CODE |
// Initialises the game public void Initialise() {
}
/// <summary> /// Loads content for all the objects, sprites etc. /// </summary> /// <param name="contet">This parameter will be passed in from main.</param> public void LoadContent(ContentManager content) {
}
// This is the update function for the game. public void Update() {
}
/// <summary> /// This is where everything is drawn the screen. /// </summary> /// <param name="spriteBatch">This is our spritebatch, also passed from main.</param> public void Render(SpriteBatch spriteBatch) {
} |
Hopefully you can see where this is going now. To set this up to run in the pipeline, we need to change a couple of things. Go back to Pipeline.cs, underneath this:
| CODE |
GraphicsDeviceManager graphics; ContentManager content; |
Add this:
| CODE |
| Game game = new Game(); |
Now we can use that Game class we just wrote as an object, and it's been instantiated. So in the Initialize function just below, below the TODO: comment, add:
This will, from now on, always run what we have inside Initialise inside our game. Just like this, add game.LoadContent(); in the LoadContent function of the pipeline, but this time you will have to pass in content, as a parameter. This variable is the ContentManager we're using, and is what we use to load assets. It should look like this:
| CODE |
protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { game.LoadContent(content); }
// TODO: Load any ResourceManagementMode.Manual content } |
After this, do the same sort of thing in Update, and add our game.Update(); function where the // TODO: comment is.
This leads us to rendering our game. Before you can render it you need to set up a SpriteBatch object, this is what we use to draw 2D images to the screen. So go back to where we declared Game game = new Game(); and add underneath:
| CODE |
| public SpriteBatch spriteBatch; |
It has now been declared, and it needs to be initialised, so in the pipelines initialisation function, beneath your game.Initialise(); add:
| CODE |
| spriteBatch = new SpriteBatch(graphics.GraphicsDevice); |
This passes the spriteBatch constructor our graphics device as a parameter, so it knows where it's drawing to. If you don't know what the graphics device is, think of it as the programmatic representation of your graphics card, since that is basically what it is. Now this has been done, we can use it to render our stuff. We want to to begin the spritebatch, so it knows it's time to start drawing, call our own render method and pass it the spritebatch, so we can use the spritebatch to draw all our objects, and then end the spritebatch. Once your changes have been made, it should look like this:
| CODE |
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// New code start spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
game.Render(spriteBatch);
spriteBatch.End(); // New code end
base.Draw(gameTime); } |
If you hit F5 now you should see the same clear screen as you did before. This is good, it means you didn't break it. Now we can do something a little more interesting than a clear screen.
To keep with the object orientation, we're now going to add another class. But to make sure these things don't take weeks to write, and I don't have to repeat myself, I'm going to continue assuming you picked up something further up in the tutorial. So create a new class called 'Object', and give it exactly the same functions as Game, remember to add the using statements too. From here we have a basic structure of the object. Now we have to consider the attributes this object has, that make it an Object. We need to see it, so it needs a sprite, we need to know where it is, so it needs a position, and we need to know if its moving and how fast, so it needs a velocity. Add the following variables to the top of your object class:
| CODE |
// Member variables Vector2 position; Vector2 velocity; Texture2D texture; |
Vector2 holds X and Y positions, these can have various uses, which you'll see more of later, and Texture2D is a type that stores a texture. So now that we have these properties as part of the class, they could do with some values. First we should add that texture.

The above is an example sprite I created in about 2 seconds, to use as an example. Save it, and go back to the IDE. Right click in the solution explorer, Add->Existing Item.. Change the Files of Type drop down to 'Content Pipeline', and then go looking for your block and click Ok. Because of XNAs helpful content system, we can reference it by a content name, rather than start giving it long directory links with the name. Go to your LoadContent function inside Object and add the following texture loading code:
| CODE |
| texture = content.Load<Texture2D>("block"); |
Be sure that “block” represents your asset name, this can be seen by clicking on the asset in the solution explorer, and looking in the properties window at the top. Now that's in, we don't have to worry about it, because it will be handled by the game and the pipeline later. We should give it a position and a velocity though. In your Initialise function, add the following:
| CODE |
position = new Vector2(20, 20); velocity = new Vector2(2, 2); |
We will now use both of these to start updating and rendering the object. In your Update function, you will need it to add the velocity to the position each time:
| CODE |
| position += velocity; |
Doing something like that would be fine, now in Render, we will use the position and the texture to draw the object to the screen. We passed in the spritebatch so that it could draw the object, now we must use spritebatch's Draw function to do this:
| CODE |
| spriteBatch.Draw(texture, position, Color.White); |
The last parameter in that function doesn't really matter. It tints the texture depending on what you put there. If you set it to white it will not tint it, other colors will have different results. Your object is now set up and ready to use. We need to create one in Game to do this. In normal game development, you would have something like an object manager, that did things like this, to keep it clean and dynamic, but that is for another time. Add:
| CODE |
| Object box = new Object(); |
To the top of your game class and then inside each relevant function, call the same function from object. In initialise call box.Initialise(), etc. Remember to pass it the parameters, like box.Render(spriteBatch); we passed them into game so that we could use them here.
Hit F5 now, and if you succesfully completed that part of the tutorial, you should see your box go flying diagonally across the screen. Now that you have your object on the screen and moving. It's time to add the functionality to move it yourself. Go to the Update function in the pipeline and add this:
| CODE |
| KeyboardState keys = Keyboard.GetState(); |
Make sure to add that above game.Update. I'm sure you realised it could get tedious having to click the close button on the window every time you wanted to exit, so add this code underneath.
| CODE |
if (keys.IsKeyDown(Keys.Escape)) this.Exit(); |
This checks every update (currently about 500-600 times per second) to see if the escape key is pressed. If it is, it calls this.Exit(), which ends the program. In the update function of the Object class, remove the part that adds the velocity to the position, we wont be using the velocity for the moment, andd now add KeyboardState keys = Keyboard.GetState(); again in there. We can use this to move our sprite around based on key input. Then, shortly after, XBOX controller input. Add this below that code in your Object class:
| CODE |
if (keys.IsKeyDown(Keys.Up)) position.Y -= 2;
if(keys.IsKeyDown(Keys.Down)) position.Y += 2;
if(keys.IsKeyDown(Keys.Right)) position.X += 2;
if(keys.IsKeyDown(Keys.Left)) position.X -= 2; |
This does the same as the part that checks for escape, but it changes the position of the texture instead of closing the program. Press F5 and you should be able to drive it around with the directional keys. If you want to use the XBOX controller to move it around aswell, it's a fairly similar process:
| CODE |
// XBOX Input if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y > 0.5f) position.Y -= 2f;
if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y < -0.5f) position.Y += 2f;
if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X > 0.5f) position.X -= 2f;
if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X < -0.5f) position.X -= 2f; |
For the final part of this tutorial, we're going to fix that annoying problem of it going off the edge of the screen. This is a very very basic implementation of some collision detection. What we need to do is check whether the edges of the texture are outside any of the edges of the window, and then correct its position before drawing. So add in the following code to check that the sprite isn't going out of bounds:
| CODE |
// Check boundaries if (position.X < 0) position.X = 0;
if ((position.X + texture.Width) > 800) position.X = (800 - texture.Width);
if (position.Y < 0) position.Y = 0;
if ((position.Y + texture.Height) > 600) position.Y = (600 – texture.Height); |
You should now find that if you hit F5, you can move your sprite around, but it cant escape the screen. From this you should be able to figure out how to have sets of stationary sprites, sets of sprites that can move on their own using the velocity, and something that you can control yourself.