This worksheet shows you how to create a very simple C#/XNA application which moves and rotates simple sprite images. This application will be too simple to be regarded as a proper game.
When you've completed this worksheet, you should be able to:
To get the most out of this worksheet you should do the following:
If you are unable to finish any of these worksheets in one go, then this is what you should do to make sure that you can resume it from the point you finished, without having to start from scratch:
You will need to download and unzip these graphical assets for use in these worksheets:
It is important to follow these steps closely. If you get stuck then you should ask your teacher (or one of your friends). If several of you get stuck then you really should tell the teacher as it probably means there's a problem with the worksheet!
Here's what we want you to do. We suggest that you put a tick beside each step as you complete it.
The main window now opens and should look something like this:

Look carefully at the right hand window frame you'll see an entry named Game1.cs, this file contains the statements for your program. These statements are visible in the left hand frame. To give you a head start, when you create a new project you get a game skeleton for free!
The next step is to select a sprite image and load it into XNA Game Studio. This process triggers an XNA feature called the Content Pipeline which loads the file into your project so that it's available to the game.

XNA Game Studio now loads the file into the project and its name now appears in the Content section of the Solution Explorer. Interestingly, although the file was originally in PNG format, the XNA content pipeline changes it to a completely different format
The properties window opens up below the Solution Explorer:

Notice that the Asset Name for this image is "Balloon" and not "Balloon.png". Now that the file has been loaded into the XNA Content Pipeline, it is no longer necessary to remember that its original format was PNG.
Although we've loaded the sprite image into the project, we need to make some additions to the game skeleton for this project. We need to make changes in three places to make the sprite visible.
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D balloonTexture;
This defines a field of this class into which we will store the sprite bitmap.
LoadContent() method.
balloonTexture = this.Content.Load<Texture2D>("Balloon");
Notice that the IDE tries to help you as you type. For example, when you type the first
few letters of balloonTexture, a window pops up offering a list of suggested
completions. Just scroll down to the correct word and press TAB to enter it into the file.
In this way you can enter most of the line without having to type all the words in full,
except for the final quoted "Balloon".
Also note that the quoted name is "Balloon" and not "Balloon.png". This is the Asset Name property which we saw earlier.
Draw() method and put the following lines after the TODO comment:// TODO: Add your drawing code here spriteBatch.Begin(); Vector2 position = new Vector2(100, 200); spriteBatch.Draw(balloonTexture, position, Color.White); spriteBatch.End();
The program starts and, all being well, should open up a game window showing a single red balloon:

This isn't particularly exciting but it's a start...
We can liven up the program by making the sprite move about the screen. To do this we first create class
fields for the sprite's X and Y positions, and change the Vector2 position object that we set up in the Draw()
method. We can change the sprite's X and Y positions within the Update() method.
balloonTexture:
Texture2D balloonTexture;
Texture2D balloonTexture; int balloonX = 400, balloonY = 300;
// TODO: Add your drawing code here spriteBatch.Begin(); Vector2 position = new Vector2(balloonX, balloonY); spriteBatch.Draw(balloonTexture, position, Color.White); spriteBatch.End();
To make the sprite move, we need to change its X and/or Y position values. The place to do this is in the Update() method
which is guaranteed to be called 60 times per second.
Update() method and put in the following line after the TODO comment.// TODO: Add your update logic here balloonY -= 1;
This will have the effect of subtracting 1 from the sprite's Y position, thus moving the sprite upwards at the rate of 1 pixel per update (or 60 pixels per second).
No doubt you discovered that a sprite can either be stationary, or moving at exactly 1, 2, 3... pixels per update (60, 120, 180... pixels per second). This is quite a coarse setting and it would be quite a limitation if our games were restricted to these speeds.
The problem occurs because we've specified the X and Y positions as int values;
if we were to use a floating point value then we could add a fractional value at each update
and obtain slower speeds. This faces us with a problem: do we define the sprite's positions
as double or float? There is no obvious or overwhelming reason
to use one and not the other, so in the end we must make an arbitrary decision. In these
worksheets we'll use double whilst noting that we can make all our games
work just as well using float. Once we've made a decision we should stick with
it - it would be a recipe for chaos to use double and float in
the same program!
balloonX and balloonY; change the data type to doubleDraw() method since the constructor for the
Vector2 position object doesn't like doubles and actually wants floats! We can keep it happy by type casting the
positions to float like this:// TODO: Add your drawing code here spriteBatch.Begin(); Vector2 position = new Vector2((float) balloonX, (float) balloonY); // Type casts to float spriteBatch.Draw(balloonTexture, position, Color.White); spriteBatch.End();
Right now you might be thinking that we made the wrong decision to use double; if we'd use float then we wouldn't
need the type casts. In this case you're right, but there are situations where it looks like float is the wrong decision
and double is better! Having made the decision to use double, the best thing is to stick with it and accept we're going
be putting type casts around the place.
Update() method so that the sprite's upward velocity is now 0.5
pixels per update:// TODO: Add your update logic here balloonY -= 0.5;
For this part of the worksheet, we'll no longer give you step-by-step instructions. Instead we'll suggest more activities for you to do to consolidate what you've learned so far. DO NOT SKIP OR SKIMP ON THIS SECTION. It's easy to follow instructions and this can lead you to a mis-placed confidence. You need to repeat an activity several times to ensure that you can remember what to do.
Activities:
Texture2D field name dartTexture, together with fields for
its X and Y position, called dartX and dartYTexture2D fieldDraw() method to draw the dart sprite.Update() method to move the sprite around the screen at a fixed
velocity.You may have noticed that the auto-completion feature of XNA Game Studio offers
seven different options for the spriteBatch.Draw() method. So far we've been
using one of the simpler versions, but now it's time to use one of the more complex versions
The complex spriteBatch.Draw() methods offer special options for drawing a
sprite. These options include horizontal and vertical flipping, increasing or decreasing
the sprite size, and rotating the sprite. Let's look at how we rotate the sprite graphic.
Here is the version of the spriteBatch.Draw() method we'll need:
spriteBatch.Draw(dartTexture, position, null, Color.White, (float) dartRotation, origin, 1.0F, SpriteEffects.None, 0.5F);
The parameter we're most concerned about here is the (float) dartRotation.
This specifies an angle which XNA will draw the sprite.
Vector2 origin. Since the dart image is 48x96 pixels, we'll set the origin to the centre
point: 24, 48.
double dartRotation = 1;
Draw() method, remove the call to spriteBatch.Draw() which draws the dart image
and replace it by these two statements:Vector2 origin = new Vector2(24, 48); // Image centre point spriteBatch.Draw(dartTexture, position, null, Color.White, (float) dartRotation, origin, 1.0F, SpriteEffects.None, 0.5F);
Note that it is standard for computer systems to measure degrees using Radians and not degrees. One radian is approximately 57 degrees.
Update() method so that the value for dartRotation is changed by a small amount
each time, causing the dart to rotate. Be sure to use a small value (say 0.05) or the sprite
will appear to rotate very quickly and you will be faced with aliasing effects.
Vector2 origin so that rotation takes place around
a different pixel. What happens if either of the values are negative, or greater than the
actual size of the image (48x96)?
When you've finished all the steps above, you need to close down XNA Game Studio as follows:
Some of you may never have heard of radians before. Most serious scientists, engineers and mathematicians don't use degrees to measure angles, they use radians. This is because they are much easier than degrees to manipulate mathematically.
If you're not familiar with the concept then you should spend half an hour or so reading up about them. Good places to start are: