December 6th, 2007

Let’s Talk Textures!

Beginner Game Tutorials, 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!

Thanks for reading! I'd love to hear your thoughts, feel free to leave a comment below. Don't forget to subscribe to my RSS Feed!
Share and Enjoy:
  • Print
  • Digg
  • Twitter
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

Back Top

Moving Stuff Around in XNA! Animated Textures

Responses to “Let’s Talk Textures!”

  1. Hi Nazeeh,

    Thank you for creating a new resource for XNA development. I am not sure what your plans are but I would like to suggest that you begin creating some more advanced articles. It seems that everyone who writes about XNA wants to cover the most basic aspects. 2D textures have been covered to death. How about some fundamentals of 3D or engine design?

    That would keep me coming back to your site.

  2. Thank you for your feedback!

    So far my plans are to cater for people that have never done any game development at all. As I was learning, and still am, a lot of the basics were not fully covered. There were always gaps that frustrated me. I hope to cover that stuff as I move on to the more advanced stuff.

    I really do appreciate the feedback though! For now, I leave the advanced stuff to the insanely capable hands of Shawn Hargreaves :)

  3. Greaaaat tutorials!
    Most tutorials on the web indeed jump too far too quick to my taste – I like to feel im grasping everything that is going on. But I have to agree with Robert, same level 3D tutorials are impossible to find :( So publishing a few of those would be extremly helpful.

    Thanx a again :D

    Yuri Shmorgun at March 1, 2008 4:39 pm
  4. commenting usually isnt my thing, but ive spent an hour on the site, so thanks for the info

  5. Thanks for sharing, I like your tutorials. They are really helpfull to me since I’m new to programming. Thanks alot!

  6. When I tried to do this lesson, it gave me an error that said “Error 1: The name ‘background’ does not exist in the current context.”, and I can’t figure out how to fix it. Any advice on how to fix that?

  7. I have the same problem as James, and I think it’s because of the variable. I can’t figure out how to set a variable for my background.

    Have a variable declared for it:

    Texture2D background;

    This is the part I don’t understand how to do.

  8. To Harris : To declare a variable write Texture2D background; under the default line of SpriteBatch spritebatch;

    Great site btw! Three years after you write this, it’s still a huge help for me :)

  9. Thanks for the comment Zaza :) I am really happy that some people still find this content helpful.

  10. thanks for the great tips

  11. this is awesome, this is what we are using in my game dev. class at college. the only thing i have found weird is that my file for this wont run, when i write the spriteBatch for the background it wont read it and cant solve it!!! nazeeh HELP, and thanks if you do

  12. Hey Twiggz, you’re gonna need to give me more info ;)

  13. it says that it cant read the backgound this or something like that. but it might be that i dont know how to declare a variable for it. i feel like a total noob but whatever

  14. The tutorials are excellent, thank you especially for explaining each step rather that just saying what to write, it helps to actually understand rather than just know what to write.

    Keep it up,

  15. Thanks for the articles. I installed C# 2010 express and XNA recently. I am trying out samples that you have posted. Good learning for me. :)

  16. How do you resize the box? (#2)

  17. was about to stop searching when I finally found your site! THX !

  1. No trackbacks yet.

Leave a Reply

Back Top