Happy Holidays Everyone!

Posted in News on December 24th, 2007 by nazeeh

Just wanted to make a quick post wishing everyone Happy Holidays and Happy New Year! I hope everyone is having a great time celeberating! More tutorials coming your way soon :) In the meantime, enjoy the holidays!

Time for Input!

Posted in Beginner Game Tutorials on December 19th, 2007 by nazeeh

Now that we have learned how to render basic 2D textures and can actually start making a game, we probably should talk about how Input works in a game. Unless your game is one where the player has to sit there and just stare at it (at which point you’re probably attempting a hypnosis game for some disturbing reason… do let me know if you got a working version though), you want to have them actually control something in it. So how does Input work in XNA Game Framework? Turns out that it’s pretty simple actually. Let’s talk Input!

Overview of how Input works

Input in XNA Framework is quite simple to use you’ll be pleasantly surprised. You can read input data from a keyboard, mouse and variety of supported game pads (Xbox 360 controllers, Guitar Hero controller, Rock Band drums, etc).

Where in my code do I read and process input? Simple: In the Update method of your Game class! To read input, you will be using one of the following 3 classes based on the device you want to read from:

  1. Keyboard Class: For keyboard input
  2. Mouse Class: For reading the Mouse input
  3. GamePad Class: For reading from a varitey of supported gamepads and controllers.

The way it works is that every one of these classes has a GetState() static method that you call. This method returns either a KeyboardState, MouseState or GamePadState object back to you. This object has data for the state of the input device when the GetState() method was called. So for instance, the MouseState object will have information such as mouse cursor location, the state of all the buttons on the mouse (pressed or released) and the scroll wheel value. You simply read the values and act on them.

Here’s a thought for you though. The call to the GetState() method returns a snapshot of the state of the device at the time you made the call. Since you call this in the Update() method of the game class, it gets called 60 times a second. So if for instance you are writing a shooting game and will have the player use the mouse button to shoot, you might check the MouseState.LeftButton property to see if the button is pressed or released. If it’s pressed, you will have the game shoot. The nasty surprise you’ll quickly run into though is that the game will fire at an alarming rate vs just one shot per mouse click! Why? Because you are checking on the Pressed button state in the Update loop that gets called 60 times per second. Since most players can’t click and release the button in 1/60th of a second, they probably will have it held done for longer and all those will come through as Pressed giving the wrong result of multiple shots until the button is released.

So how do you deal with that? The answer is quite simple. Let me show you via some code. Let’s say we want to check if the left mouse button was pressed or not. The code would be as follows:

First we declare a member variable in our class of type MouseState (line 5):

   1: public class Game1 : Microsoft.Xna.Framework.Game
   2: {
   3:     GraphicsDeviceManager graphics;
   4:     SpriteBatch spriteBatch;
   5:     MouseState previousMouseState = Mouse.GetState();

We initialize the variable by calling Mouse.GetState() like in the code. This grabs the state of the mouse when the game is about to start.

When we read the state of the mouse in the Update code, we want to register a mouse click when the CURRENT state of the left mouse button is Released and PREVIOUS state for it was Pressed. This way we will know that the button was pressed and just got released at the time we called GetState(). Then at the end of the Update method, we save the Current MouseState we just read as the PreviousMouseState so that we can use it next time Update is called. Here, check out the code, it will become very clear:

   1: protected override void Update(GameTime gameTime)
   2: {
   3:     // Grab the current state of the mouse
   4:     MouseState CurrentMouseState = Mouse.GetState();
   5:
   6:     // Now we see if the left mouse button was clicked or not
   7:     if (PreviousMouseState.LeftButton == ButtonState.Pressed
   8:         &&
   9:         CurrentMouseState.LeftButton == ButtonState.Released)
  10:     {
  11:         // Left mouse button was clicked! 
  12:         // Do something with it!
  13:     }
  14:
  15:     // Record the CurrentMouseState
  16:     // as PreviousMouseState
  17:     PreviousMouseState = CurrentMouseState;
  18:
  19:     base.Update(gameTime);
  20: }

Let’s dissect the code:

  • Line 4: We get the current state of the mouse and save it.
  • Lines 7-9: We check to see if last time we called update the button was pressed and now it is released. This means we got a mouse button click!
  • Lines 11,12: Do whatever the game is supposed to do in response to a button press (shoot something)
  • Line 17: Save the CurrentMouseState in PreviousMouseState so that you can use it next time Update is called.

Simple eh? The same method applies to Keyboard and GamePad classes as well. Just save the previous state and compare it with the current state. This way you can get a clear reading of when a player has pressed a button or not. Some game play actions of course require the player to keep a button pressed for instance, these don’t need such a method, you just check if the button is pressed or not and do whatever action in response as long as the button remains pressed.

Just for completness sake (and to make this post look bigger and more important that it really is), here’s some code for how this works for both a Keyboard and a GamePad.

Keyboard

Here’s the code to check for the Left arrow key on the keyboard, I removed all non-essential parts:

   1: public class Game1 : Microsoft.Xna.Framework.Game
   2: {
   3:     GraphicsDeviceManager graphics;
   4:     SpriteBatch spriteBatch;
   5:     KeyboardState previousKS = Keyboard.GetState();
   6:
   7:     protected override void Update(GameTime gameTime)
   8:     {
   9:         // Grab the current state of the mouse
  10:         KeyboardState CurrentKS = Keyboard.GetState();
  11:
  12:         // Now we see if the left mouse button was clicked or not
  13:         if (previousKS.IsKeyDown(Keys.Left)
  14:             &&
  15:             CurrentKS.IsKeyUp(Keys.Left))
  16:         {
  17:             // Left arrow was pressed! 
  18:             // Do something with it!
  19:         }
  20:
  21:         // Record the CurrentMouseState
  22:         // as PreviousMouseState
  23:         previousKS = CurrentKS;
  24:
  25:         base.Update(gameTime);
  26:     }
  27: }

GamePad

Now let’s see how this works for a GamePad like the Xbox 360 controller:

   1: public class Game1 : Microsoft.Xna.Framework.Game
   2: {
   3:     GraphicsDeviceManager graphics;
   4:     SpriteBatch spriteBatch;
   5:     GamePadState previousGS = GamePad.GetState(PlayerIndex.One);
   6:
   7:     protected override void Update(GameTime gameTime)
   8:     {
   9:         // Grab the current state of the mouse
  10:         GamePadState CurrentGS = GamePad.GetState(PlayerIndex.One);
  11:
  12:         // Now we see if the left mouse button was clicked or not
  13:         if (previousGS.Buttons.A == ButtonState.Pressed
  14:             &&
  15:             CurrentGS.Buttons.A == ButtonState.Released)
  16:         {
  17:             // A button was pressed! 
  18:             // Do something with it!
  19:         }
  20:
  21:         // Record the CurrentMouseState
  22:         // as PreviousMouseState
  23:         previousGS = CurrentGS;
  24:
  25:         base.Update(gameTime);
  26:     }
  27: }

Check out Line 5, do you notice the argument to GamePad.GetState? That’s the PlayerIndex enumeration value you need to specify. Since an Xbox can have up to 4 controllers plugged in, you need to specify which one you want to read from. In this case, we specified PlayerIndex.One meaning controller #1. To read input from multiple controllers, you need to declare PreviousGameState variables for each PlayerIndex you want. Just do the same thing for more than one controller like you would for one.

Final thoughts

One of the things you might want to do is write an input handling class for your game. Something to encapsulate all the input handling code for your game. You can go totally wild with how you implement it. You can make it event driven so code can subscribe to certain events such as “AButtonPressed”, etc. Be creative! These classes will live with you for a long time ;)

Quick Questions, Quick Answers!

Posted in Beginner Game Tutorials on December 18th, 2007 by nazeeh

For this post, I decided to spend some time answering some frequently asked questions that some of you may or may not be thinking of right now. I remember at this stage of my learning, I started to wonder about how to do certain things. So let’s dive right in!

Eh…where’s my mouse pointer?!

Yeah…this is one I had pretty quick after using XNA Game Studio. I noticed that whenever I ran my game and moved the mouse over it, POOF!, the mouse pointer is gone. Working on the team that develops XNA has the awesome benefit of me being able to walk up to one of the developers and be like “yeah…dude…wtf?”. The answer is pretty simple, putting the following code in your Initialize method will make the mouse pointer visible:

this.IsMouseVisible = true;

The default value is “false”, hence why we don’t see it by default.

I want to run my game at a different resolution, how?

Pretty soon after you start playing around with XNAGS, you will want to run your game at a different resolution than the default one. How do you change it? Here’s the code:

   1: public Game1()
   2: {
   3:     graphics = new GraphicsDeviceManager(this);
   4:     Content.RootDirectory = “Content”;
   5:
   6:     // Set the game’s resolution to 1680×1050
   7:     this.graphics.PreferredBackBufferWidth = 1680;
   8:     this.graphics.PreferredBackBufferHeight = 1050;
   9: }

Simple :) Just make sure it’s in the Constructor vs the Initialize method.

Give me fullscreen!

Alright, a follow up question is: How do I make my game run in Fullscreen mode?

   1: protected override void Initialize()
   2: {
   3:     // If we are not Fulscreen, let’s be fullscreen!
   4:     if (!graphics.IsFullScreen)
   5:         graphics.ToggleFullScreen();
   6:
   7:     base.Initialize();
   8: }

You can do it by either calling the ToggleFullScreen() or directly setting the value of IsFullScreen to true for fullscreen or false. Both work just fine. See? We want you to have options!

How do I tell if my game is “Active” or in focus?

This is one that I ran into when I was working on a simple sample. I used the mouse to control the sample (was rotating a cube or something amazing like that) and I noticed that when I moved the mouse when the game wasn’t active and the cube still rotated. Hmm..that’s odd. Why is my game handling mouse movements even when it’s not the actively focused application? My first thought was “Aha! BUG! The devs screwed up! Time to go rub it in!”. Five mins later, I come back after talking to one of the devs and it’s not a bug (sigh…fine..almost had him). This is what you want to do:

   1: protected override void Update(GameTime gameTime)
   2: {
   3:     if (this.IsActive)
   4:     {
   5:         // Add code that you only want to run when 
   6:         // the game is the active and in focus
   7:         // application. 
   8:         //
   9:         // Stuff like input handling for instance is good 
  10:         // here.
  11:     }
  12:
  13:     base.Update(gameTime);
  14: }

All you need to do is check the IsActive flag. If it’s true, your game is in focus.

My Update method is called 60 times per second, I want faster!

The Update method gets called by default 60 times a second. This makes sure that your game runs at the same pace on any device it runs on. But sometimes you may want to change that to make it run as fast as possible. This means you want it to be called as often as possible by the XNA Framework. To do that, here’s the code:

   1: protected override void Initialize()
   2: {
   3:     this.IsFixedTimeStep = false;
   4:
   5:     base.Initialize();
   6: }

and in the Update method, you can find out how long it has been since the last Update call like this:

double elapsedTime = gameTime.ElapsedGameTime.TotalMilliseconds;

That’ll do it.

How to I set the title of the game window?

Alright, this one you probably would have spent like 20 seconds to find out how to do. But hey, I just saved you 20 seconds eh? Yeah…that’s how I roll.

Setting the title of the Window in non-Fullscreen mode is useful since it’s an easy and fast way to display some short debugging info for example. Something like Frames Per Second can be displayed here pretty quickly. This is how to do it:

   1: protected override void Initialize()
   2: {
   3:     this.Window.Title = “I am an awesome game! No really!”;
   4:
   5:     base.Initialize();
   6: }

See? now you have 20 seconds extra to do whatever with.

That’s it for now! If you have any other questions, post them as comments and I’ll see that they get some sort of an answer. Have fun!

XNA Game Studio 2.0 RELEASED!

Posted in XNA Game Studio on December 15th, 2007 by nazeeh

I am very excited to share the news about XNA Game Studio 2.0 having been released! You can grab your copy from here. Ok, fine, my post is a few days late (XNA Game Studio 2.0 was released last Thursday 13th Dec), but I have an excuse! I got on an airplane heading back home to Egypt to visit my family. I am in Egypt now and just barely got over the jet lag and the inital storm of “hey! nice to see you!!”. So what’s new??

Here’s a quick list of what’s new in this awesome version:

  • Networking Support
  • Expanded Support for Visual Studio 2005 Products (that means Visual Studio 2005 Pro and up, an no, no support for Visual Studio 2008)
  • XNA Game Studio Device Center and Easier Xbox 360 Connectivity
  • Cross-Platform Game Project Converter
  • Updated Game Project Format
  • Integrated Game Content Projects
  • XNA Game Studio Package Utility
  • Updated Microsoft Cross-Platform Audio Creation Tool (XACT)
  • Parameterized Processors
  • …and more! Have a look at the “What’s new” page in the docs for the full list of changes.

All my tutorials have been done using XNA Game Studio 2.0. So it’s a good idea to upgrade to that version if you haven’t by now.

Have fun! I will get to writing my next tutorial very soon. Just gotta get to feeding my camel first.

Animated Textures

Posted in Beginner Game Tutorials on December 10th, 2007 by nazeeh

In my last post, we talked about textures in general and how to use them. This post will talk about a fun and important aspect of using textures in 2D games: Animation. Say you have a 2D game and you have Wizard character that the player controls and it can cast a spell. It would be boring if the wizard did not have any cool animation to indicate that he is casting a spell. This is where animation comes handy! We can use animation to make a 2D image appear to be alive and have motion.

So how do you create such an animation? First you need to have the actual animation designed. I found a free-to-use animated GIF on the web that I will use for this post:

Doing_magic

As you can see from the image, it’s a simple animation of a wizard using a wand. We want to take this wizard and use him in our game and have this animation be available.

So how do we do that? Every animation is made up of what’s called “Frames”. That means that the animation is actually a series of images each showing one step of the animation. For this one, you have the following 3 frames that make up the animation:

Doing_magic

It should be clear now how the animation works, right? It’s 3 frames that you display one after the other with a long enough delay in between to make it look good. So let’s see how we can get this animation to work in a game we build.

Create the animation into a horizontal strip

First thing you need to do is create the animation you want somehow. One way I tend to do it is by either finding animated gifs on the web that are “free” to use, or built them on my own. I can’t go into how to build them now since that’s outside the scope of this post. But basically, you need to build something like the second image up there. A horizontal strip that has all the frames of the image on it.

The image strip that contains your frames should have a correct size though! Every frame should be exactly the same width as the others. So if you have 3 frames in your strip, the width of the strip should be 3 x Width of one frame. You’ll see why later.

If you have an animated Gif like mine here, you can use this really cool tool I found on the web to convert it to a strip: Bitstrip.

Bitstrip is a simple tool that can convert animated GIF to a horizontal strip. To do that, fire up the tool, it has a very simple UI:

image

Click on “Browse to GIF file” button and find your GIF file.

Click on “Horizontal” button to see what the horizontal strip would look like.

With the Horizontal view open, click on “Save output as” and save the output file somewhere on your machine. It will be a .bmp file that looks like this:

image

What is all that pink???? Nothing to worry about! That’s the color the tool uses to indicate that this should be transparent. Fortunately, that is the same color that a lot of tools (and XNA Game Studio) use to indicate transparency. This technique is called Color Keying (you can read about more about it on Wikipedia).

Animating the texture in code

So now that we have the final texture we’ll use, it’s time to figure out how to animate it using code. Let’s examine what we’ll need to do:

  1. Need to figure out how many frames we have (nothing to figure out, we know from the image we created)
  2. Figure out the width of a single frame. Easy. Frame Width = Total Width of strip / number of frames.
  3. We need to render frame 1, then wait for sometime, then render frame 2, wait for sometime, etc until we reach the end of the frames. We can then loop back again to frame #1.

I happen to have a class that I wrote that specifically does what we listed just now. I call it: AnimatedTexture. Here’s the code:

 

   1: class AnimatedTexture
   2: {
   3:     private Texture2D aniTex;
   4:     private int CurrentFrame = 0;
   5:     private int numberOfFrames = 0;
   6:     private int msBetweenFrames = 0;
   7:
   8:     private Rectangle rect;
   9:
  10:     private int width = 0;
  11:     private int height = 0;
  12:
  13:     float timer = 0;
  14:
  15:     public AnimatedTexture(Texture2D texture, int numFrames, int msBetweenFrames)
  16:     {
  17:         this.aniTex = texture;
  18:         this.numberOfFrames = numFrames;
  19:         this.msBetweenFrames = msBetweenFrames;
  20:
  21:         this.width = texture.Width / numberOfFrames;
  22:         this.height = texture.Height;
  23:
  24:         // Init rectangle
  25:         rect.X = 0;
  26:         rect.Y = 0;
  27:         rect.Width = width;
  28:         rect.Height = height;
  29:     }
  30:
  31:     public void Update(GameTime gametime)
  32:     {
  33:         timer += gametime.ElapsedGameTime.Milliseconds;
  34:
  35:         if (timer >= msBetweenFrames)
  36:         {
  37:             timer = 0;
  38:
  39:             if (CurrentFrame++ == numberOfFrames - 1)
  40:                 CurrentFrame = 0;
  41:
  42:             rect.X = CurrentFrame * width;
  43:             rect.Y = 0;
  44:         }
  45:     }
  46:
  47:     public void Render(SpriteBatch sb, Vector2 position, Color color)
  48:     {
  49:         sb.Draw(aniTex, position, rect, color, 0, Vector2.Zero, 2.0f, SpriteEffects.None, 0);
  50:     }
  51:
  52: }

Let’s have a closer look at the code:

Lines 3-13: Local variables that we will use

Line 15: This is the constructor of the class. It takes the following arguments:

  • Texture2D texture: This is the strip we prepared. Load it up using the Content pipeline and pass it here.
  • int numFrames: This is the number of frames in the strip. User provided.
  • int msBetweenFrames: This is how many milliseconds should we wait between frames. The lower, the faster the animation.

Lines 21,22: Here we calculate the width and height of a single frame. Simple.

Lines 25-28: We initialize a rectangle to contain the first frame in the strip. We will use this in the rendering.

Lines 31-44: This is the Update method for the class. This method calculates the values in our Rectangle to move it to contain the next frame when it’s time. Time is calculated via the GameTime object so that we can tell when to move on to the next frame. We wait for a total number of msBetweenFrames milliseconds before moving on to the next frame. Simple math.

Lines 47-50: This is the Render method. Here we use a SpriteBatch object the user passes in along with a position and color to draw the current Rectangle from the texture. SpriteBatch has an overload that lets you specify a region in the texture to draw rather than the entire thing. This is why we’ve been calculating a rectangle for each frame in the Update method. We only draw the content of this rectangle each time.

Using the code in your game

Using the AnimatedTexture class we just created in our game is very easy.

Create a member variable in your Game1.cs file, in the Game1 class:

AnimatedTexture aniTex;

Load a texture in it in the LoadContentMethod:

 

   1: protected override void LoadContent()
   2: {
   3:     spriteBatch = new SpriteBatch(GraphicsDevice);
   4:     aniTex = new AnimatedTexture(Content.Load<Texture2D>(“doing_magic”), 3, 80);
   5: }

I used 80 ms as the in-between frames delay. It seemed to look fine.

Make sure to call the Update method for the AnimatedTexture in the Update method:

 

   1: protected override void Update(GameTime gameTime)
   2: {
   3:     // Allows the game to exit
   4:     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
   5:         this.Exit();
   6:
   7:     aniTex.Update(gameTime);
   8:
   9:     base.Update(gameTime);
  10: }

Finally, call the Render method in the Draw method:

 

   1: protected override void Draw(GameTime gameTime)
   2: {
   3:     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
   4:
   5:     spriteBatch.Begin();
   6:     aniTex.Render(spriteBatch, Vector2.Zero, Color.White);
   7:     spriteBatch.End();
   8:
   9:     base.Draw(gameTime);
  10: }

There you go! It’s done :) Hit F5 and you should see a cool animation running. You can move it around by adding movement code just like you would for a normal texture. Just change the position argument in the Render method for AnimatedTexture.

Have fun!

Let’s Talk Textures!

Posted in Beginner Game Tutorials on December 6th, 2007 by nazeeh

The subject of today’s topic is one that is quite interesting to me and something you will probably spend sometime playing around with. I want to talk about Textures, specifically Texture2D class in the framework. If we’re going to talk about Textures, then we will have to talk about SpriteBatch as well since that’s the class we use to draw textures on the screen.

First off, what is a texture? In its simplest form, a texture is an image. It is known by many different names that probably do have slightly different interpretations, but to me they are somewhat the same: Bitmap, Image, Picture, Sprite, etc. If you look at a game like Street Fighter 2 for instance, that is what is called a 2 Dimensional game (2D) and is completely made up of “Sprite graphics”. Which are…textures.

What do you use Textures for?

Well, the simplest example is in 2D games. All the graphics on the screen are images that you move around to simulate a world and gameplay. Just like in my previous post where we created an image of a ball and moved it around using the keyboard.

Textures are also used in 3D graphics all the time. The are used to cover the models with colors and detail to give that final polished look of a car or character. Things such as T-shirts and patterns on a model are textures. Terrain is another place where textures shine in 3D graphics. Things such as grass, rocks, etc that cover land in a game are textures.

Textures in their most basic form are really 2D arrays of numbers. A number at position X,Y that says the color for this pixel is Yellow for instance. So you end up seeing game developers using Textures as 2D arrays in their games. They store data in there that is not meant as a picture at all, will even look weird if rendered, but they instead read that data on the graphics card to achieve some interesting effects on the game. We’ll eventually see some of that stuff as we get more “seasoned’.

Creating Textures

So how do you create textures? It’s really pretty simple. You can create textures using any of the widely available image editing programs such as Photoshop, Gimp, Paint.Net and even the Microsoft Paint program that’s included in Windows by default. Anything that can save as one of the popular image types such as jpg, bmp, png, etc will work just fine.

You can also create images programmatically! You won’t use that very often in a 2D game, but you’ll find a few scenarios here and there that might present themselves.

Let’s Play with Textures!

Let’s fire up our Visual Studio and start getting familiar with Textures and what we can do with them. Create an new Windows Game project and start messing with textures!

Let’s start by giving our game a nice cool background or backdrop. The image I will use for my backdrop is one that is part of the SpaceWar starter kit that comes with XNA Game Studio. It looks like this:

image

You can use this one too if you want. Save it to your hard drive and add it to your project. Mine is already in my project:

image

Now we use it!

Have a variable declared for it:

Texture2D background;

Load it (line 5):

 

   1: protected override void LoadContent()
   2: {
   3:     // Create a new SpriteBatch, which can be used to draw textures.
   4:     spriteBatch = new SpriteBatch(GraphicsDevice);
   5:     background = Content.Load<Texture2D>(“B1_nebula01″);
   6: }

Render it (lines 5,6,7):

 

   1: protected override void Draw(GameTime gameTime)
   2: {
   3:     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
   4:
   5:     spriteBatch.Begin();
   6:     spriteBatch.Draw(background, Vector2.Zero, Color.White);
   7:     spriteBatch.End();
   8:
   9:     base.Draw(gameTime);
  10: }

Tip: Did you notice the little trickery that is in line 6? I wanted to position the image at coordinates 0,0 of the game window. I could have said “new Vector2(0,0)”, but why would I do that when Vector2 class has a nice “.Zero” static method on it that returns a (0,0) Vector2. You’ll find a similar method on Vector3 and Vector4 as well.

Hit the magic F5 key and let’s have a look at the awesomeness we just created:

image

Oh! Come on!!! The image doesn’t fit the window size correctly. Now what? I can do one of 3 things:

  1. Resize the image in some image editor to make it fit
  2. Resize the Window to make that fit the image
  3. Scale the image in the Window to make it stretch out and fit any window size.

Alright, I’ll go with option #3 since it’s easy and will work with whatever size window we have from now on. So how do we do that? SpriteBatch.Draw method has a lot of overloads, so let’s see if it has something that can help. Sure enough, it has a method that can take a Rectangle that defines the destination area to draw the image in. This will work just fine! Here’s the code:

 

   1: protected override void Draw(GameTime gameTime)
   2: {
   3:     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
   4:
   5:     Rectangle rect;
   6:     rect.X = 0;
   7:     rect.Y = 0;
   8:     rect.Width = graphics.GraphicsDevice.Viewport.Width;
   9:     rect.Height = graphics.GraphicsDevice.Viewport.Height;
  10:
  11:     spriteBatch.Begin();
  12:     spriteBatch.Draw(background, rect, Color.White);
  13:     spriteBatch.End();
  14:
  15:     base.Draw(gameTime);
  16: }

Alright, so what’s happening here?

Rectangle Struct defines a rectangle area by the X and Y coordinates on screen and a Width and Height to use. We already know that we want the image to start from (x,y) = (0,0) which is the top left corner of the screen. Now all we need to do is have it extend to the width and height of the screen and we’re golden. How do we get the Width and Height of the screen in XNA? check out lines 8 and 9. They use:

graphics.GraphicsDevice.Viewport

This class contains a lot of information regarding the details of the screen we’re drawing to right now on the graphics card. It has a Width and Height property on it which are exactly what we need. We set them on the Rectangle struct and use that in the Draw method of SpriteBatch instead of the Vector2.Zero part. Again, hit F5 and you should see:

image

Much nicer! Granted, the image is stretched out a bit and may not look good with other backdrops, but it looks fine with this one.

Taking it one step further

Ok, so now that we learned a bit more about textures and how we can resize them as we draw them, let’s learn about what we can do to mess with how they look a bit. And since now we know how to render textures on screen pretty easily, you can use my previous post to render the ball on top of this back drop since we’ll use it in the coming part.

So right now, my code that includes the ball looks like this:

 

   1: protected override void Draw(GameTime gameTime)
   2: {
   3:     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
   4:
   5:     Rectangle rect;
   6:     rect.X = 0;
   7:     rect.Y = 0;
   8:     rect.Width = graphics.GraphicsDevice.Viewport.Width;
   9:     rect.Height = graphics.GraphicsDevice.Viewport.Height;
  10:
  11:     spriteBatch.Begin();
  12:     spriteBatch.Draw(background, rect, Color.White);
  13:     spriteBatch.Draw(ball, Vector2.Zero, Color.White);
  14:     spriteBatch.End();
  15:
  16:     base.Draw(gameTime);
  17: }

Line 13 is responsible for rendering the ball. Hit F5 and you should see something like this:image

Attention: Notice how the order of call between the Begin and End of SpriteBatch matters? It will draw the textures on top of each other based on that order. If you reverse the order of drawing of the backdrop and the ball, you won’t see the ball anymore.

So let’s say that this is a game that I am making, and after a while, the ball gets some damage or something and we want to change its color to indicate that something happened to it. How do we do that? We can use another texture that is of that color I guess, but there is an easier way:

 

   1: spriteBatch.Draw(ball, Vector2.Zero, Color.Red);

This is how I am rendering the ball now. Instead of using Color.White which means “draw as is”, I am using Color.Red which means mix the colors of the texture with the color red. In this case, adding Red to White will give you Red:

image

There you go! We changed the color of the ball with a simple change in how we draw it. You can imagine making the Color argument of the Draw method a variable in your code. You can then change its value in the Update method of your game based on whatever criteria you come up with and the Draw call will always pick up that new value. In a simple fighting game I prototyped, I would add a red tint to my fighter’s colors for 1 second or so to indicate that he was hit by the other player.

Ok! That’s it for today! Next time I’ll talk some more about textures and get into how you can animate them! Getting closer to making games!

Moving Stuff Around in XNA!

Posted in Beginner Game Tutorials on December 5th, 2007 by nazeeh

In my last post, we created a very simple “Hello World” game in XNA. It wasn’t anything fancy, but it served the purpose of introducing XNA project template and getting us familiar with what’s in the code. But let’s face it, it wasn’t a game… not even close to being one. Putting text on the screen that doesn’t move is quite boring. Time to spice things up a bit and get to learn about user input while we’re at it.

You can reuse the project we created from last post if you want, or create a new one. Whichever is fine by me! Instead of boring text, we’ll use some “graphics” this time. I use the term “graphics” very loosely since the best I could come up with was this little image: