How to code games for the PC and Xbox 360
Get on the path to unlimited game programming riches
1. Your graphics card is doing all the work.
2. We can spin and scale sprites for free.
3. You can apply all sorts of pixel shader effects to your sprites.
The downside? Well, there isn't one: when we write our code, it looks like it's all done in real 2D – all the XNA wizardry is done behind the scenes. At the very least, your Draw() method should include:
GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(SpriteBlendMode. AlphaBlend, SpriteSortMode. Immediate, SaveStateMode.SaveState); spriteBatch.End(); base.Draw(gameTime);
That clears the screen to black so that we don't see the stuff we drew in the last tick, then starts drawing sprites, finishes drawing sprites, and calls base. Draw().
That last part is required, because both Xbox 360 and Games for Windows have a 'guide' system built-in that can draw a user interface on top of your game. When you end your Draw() method with a call to base.Draw(), it means 'I'm done; now let the computer draw anything else it needs before this tick is over'.
What goes between the Begin() and End() call of the sprite batch is down to you. It all gets drawn in order, meaning that if you draw one sprite then another, the second sprite will be drawn on top of the first.
The reason it all has to go inside Begin() and End() is because the sprites get batched (hence the name) into one lump before being sent to the GPU, which is faster than sending individual sprites as needed.
Get daily insight, inspiration and deals in your inbox
Sign up for breaking news, reviews, opinion, top tech deals, and more.
Making a move
Every time the Update() method gets called, it's your chance to make your game world come to life. To make your game playable, you need to read and act on player input. You need to move enemies and perhaps even create new ones. You need to look for network traffic, manipulate animations, check for collision between game objects, and a whole lot more. But in this simple little game all we do is update the player, update the asteroids, update the player's lasers, then check for any collisions between lasers and asteroids.
As your game grows, you'll need to add more and more code to this Update() method, so in the example code on your disc you'll see that I've created my own little methods for handling different updating tasks – this prevents the Update() method from becoming too cluttered. There's a lot of code here, but you can understand most of it once you get your head around one particular part:
KeyboardState keys = Keyboard. GetState();
if (keys.IsKeyDown(Keys.W))
UfoVelocity.Y -= 1.0f;
if (keys.IsKeyDown(Keys.S))
UfoVelocity.Y += 1.0f;
if (keys.IsKeyDown(Keys.A))
UfoVelocity.X -= 1.0f;
if (keys.IsKeyDown(Keys.D))
UfoVelocity.X += 1.0f;
UfoVelocity *= 0.93f;
UfoVelocity = Vector2.
Clamp(UfoVelocity, new Vector2(-10.0f, -10.0f), new Vector2(10.0f, 10.0f));
UfoPosition += UfoVelocity;
Parts of that are easy to understand: 'if IsKeyDown(Keys.W)', for example, means that the rest of the line will be run by XNA only if the W key is being pressed on the keyboard.
You can see that if the key is being held down, UfoVelocity.Y has 1.0 subtracted from it – the 'f' part is short for 'floating-point', which is a fancy programmer word meaning 'a number with a decimal point in', such a 3.1.
Subtracting 1 from UfoVelocity.Y means that the player will start to move upwards, but straight after all the keypress checks is a line that multiplies the velocity by 0.93f. Multiplying a number by another number that's less than 1 has the effect of making it proportionally smaller, so this multiplication has the effect of slowing the player down as if there were some air friction.