Tuesday, October 07, 2008

XNA Part 2 - Some Simple Drawing

Now that we have a very basic understanding of the framework of our game, we will do something equally as simple. Taking an image, bringing it into our content manager and drawing it on the screen.

There are many image formats that you can use in XNA, but I am going to suggest the PNG format for a couple of reasons. The first is that it supports variable transparency. That is parts of the image can be between 0% and 100% transparent. As opposed to GIF which is either 0% or 100% transparent or JPG or BMP which has no transparency. XNA will respect the transparency of your image, so it is a good choice. It is also a lossless format which means that it does not have the same type of artifacts that JPG has from it's compression.

So the image I'll use in today's example is one I whipped up in Blender and saved as an RGBA PNG file.

So, let's draw this guy on the screen.

First we need to add the image file to the project. First, under the content folder in the Solution Explorer, right click and choose Add, then choose "New Folder". We will make a folder called "sprites". Sprites are small graphics elements that we can use/reuse in our game. So we make a folder for them in our "content pipeline". Once we have a folder called sprites, right click on it, and choose Add, then choose Existing Item(since our graphic file already exists). Browse to your image file and double click it. You will then see the image listed in your Solution Explorer under the content->sprites folder. Right click on it and change the name of the file to "alien.png".

When your game is compiled, XNA will take the resources in the content pipeline and put them in a format it can use in your game.

Now for some code. We store an image in a XNA object called Texture2D. So first we will add a private member to our game class called alien. Go to the top of your game class and just below "SpriteBatch spriteBatch;" add the line

Texture2D alien;

This creates a class variable in our game class to hold a 2d texture (an image). Now in our "LoadContent" method we will load content into this "alien" variable. Go to the LoadContent method and just below

spriteBatch = new SpriteBatch(GraphicsDevice);

add the line

alien = Content.Load("sprites\\alien");

"Content" is the content manager, so we are telling it to load the sprites\alien file. (notice we leave off the extention, and have to escape the backslash) This returns a reference to a texture2d object and puts that reference into the alien variable.

So now we have an object containing our image data ready to be drawn.

So if we want to draw something we do it in the draw method. Scroll down to it. After the line

graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

We will add the following code.

Vector2 position = new Vector2(10,10);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();


Line 1 creates a Vector2 object with the coordinates 10,10. We will use this to position our image. Later we will move this code out of the draw method since it really doesn't belong here. All coordinates in XNA are drawn from the upper left hand corner as 0,0. Keep that in mind.

Line 2 takes our spriteBatch object and calls it's begin method. spriteBatch lets us create a batch of graphical elements and write them to the graphics card in an orderly and efficient manner. So this line begins our batch.

Line 3 adds our image drawing to the batch. There are 7 different ways you can call the spriteBatch.Draw method. The one we have used here takes our Texture2D object, a Vector2 for location, and a color from the Color enumeration that acts as a "tint" for our image. If we do not want to tint our image, we choose Color.White.

Line 4 ends our batch so it can be sent to the graphics card.

This is all the code we need to Draw our image to the game. We can compile and run our program to see the results. You should see your image drawn in your game window.


Here is the complete code for the Game1.cs file

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TutorialGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D alien;
Vector2 position = Vector2.Zero;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
position.Y = graphics.GraphicsDevice.Viewport.Height / 2;
base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
alien = Content.Load
("sprites\\alien");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
position.X += 0.15f;
position.Y = position.Y + (float)Math.Sin(position.X);
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}

1 comment:

KakashiDK said...

in XNA 4.0 thers a error in the code.
you need to define the alien as a Texture2D
in Content.Load("sprites\\alien");

Nice tutorial :)