Dream.Build.Play 2012

So I’ve been wanting to do this for quite some time and this year I think I have a decent shot at making it in time. I’ve decided to enter the Dream.Build.Play 2012 competition. The game will be a “MetroidVania” style game. The overall look and feel of the game is going to be a “2.5D” style where the characters and environments are all done in 3D, but rendered as multiple PNG’s to use as sprite sheets for the characters, and large PNG’s for the environments. I’d like to take a lot of what was great about the atmosphere from Symphony of the Night and the other Castlevania games that followed suit, but also introduce a lot more exterior environments. The only thing that bothered me about SotN was the fact that you were stuck in that one(two) castle for the entire game, unless you used the sword bros trick with the bat charge, which would allow you to get through a wall and go outside the castle, but never leave the screen to a true outdoor level. The specifics of the gameplay are being worked out as we speak, and obviously due to the time constraints on this late starting project, some features will inevitably have to be cut in order to get a submission ready before the deadline. I’d really love to do multiple playable characters, but we’ll see how it goes over the next two months before that. My first step is this project is to get a working animation engine using sprites from Symphony of the Night as placeholders while my artist does his thing and creates the art that I will need. I’ll keep this blog updated, and I’m also going to submit my RSS feed to XNA Last Dance to keep people updated in a couple of places. So that’s all for now. Hopefully I’ll have something to show very soon.

Animated Sprite Tutorial

This is the first tutorial that I ever wrote. It was originally posted on Dream.In.Code. Dream.In.Code is a programmers community with forums for just about every language that is currently used today in software development, not just game development. I suggest you manually type all of the code in this tutorial. This will help you out more than you realize in the long run. After all, we’re programmers, not copy/pasters.

The image I am going to use for this tutorial is a 16 frame sprite sheet that I created myself with the help of MSPaint. It’s an awesome tool for pixel artists as there’s no blending like you’ll find with Photoshop or some of the other high end image editing programs out there. The sprite sheet, as I already mentioned, is 16 frames wide, and only one frame tall. This means that all of the sprites for this sprite sheet are on one line as it is really simple. You could use multiple lined sprite sheets if you want, but you’ll have to change the code that this tutorial will walk you through as I am not going to go into detail on how to do it this way so I’ll stick with a single line sprite sheet for this tutorial.

Sprite Sheet

This image is a PNG file because we will need to be able to use the transparency for the background of the image so that we don’t have a large white box surrounding our sprite.

Once we have our sprite sheet, we’ll want to start an XNA project and import the image file into the content folder of the project, and I’m assuming you already know how to do this. If not, then check around other places because I’m not going to be covering that particular topic.

Once the file has been added to the project, we’ll start by adding a new class to the project by right clicking the name of the project in the Solution Explorer on the right side of the screen, choose Add->New Item, then choose Class from the window that pops up. We’ll name this class AnimatedSprite.cs. This will be the class that handles the majority of the logic behind creating an animated sprite. Once the class opens up, it’ll be mostly empty. For starters, at the top of the page, add some using statements for the XNA framework namespaces that we will be using in this file. Without these using statements, you’ll run into a lot of errors.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

Now that we have that simple step out of the way we can start the fun stuff. First thing we’ll do is create some variables inside the class.

Texture2D spriteTexture;
float timer = 0f;
float interval = 200f;
int currentFrame = 0;
int spriteWidth = 32;
int spriteHeight = 48;
int spriteSpeed = 2;
Rectangle sourceRect;
Vector2 position;
Vector2 origin;

Let’s take a minute to explain these variables so that we’re completely clear on what they are and what they’ll be used for. The spriteTexture variable is pretty self explanatory. It’s a 2d texture object that we are going to use as our sprite. The timer variable is a floating point number that will be used for creating a certain amount of time that is required to pass before the sprite will move to the next frame. This prevents the animation from being incredibly fast as XNA will update roughly 60 times per second. The interval variable is a floating point number that we will use to determine how often we want to step to the next frame in the animation. The currentFrame variable is used to keep track of the current frame of the animation. The spriteWidth and spriteHeight variables are just used to keep track of the width and height of our sprite as their names suggest. The spriteSpeed variable is used to set the speed that the sprite actually moves across the screen, which is to say that the position of the sprite will change by this much each time we tell it to change. The sourceRect variable is the rectangle in which our sprite will be drawn. The position and origin variables are 2d vectors that will be used to denote where the sprite is on the screen and the center of our drawn sprite respectively.

Alright, now that those variables have been explained, let’s move on to the part where they’re actually being put to use. The following code just sets up the properties for getting and setting the above variables.

public Vector2 Position
{
	get { return position; }
	set { position = value; }
}

public Vector2 Origin
{
	get { return origin; }
	set { origin = value; }
}

public Texture2D Texture
{
	get { return spriteTexture; }
	set { spriteTexture = value; }
}

public Rectangle SourceRect
{
	get { return sourceRect; }
	set { sourceRect = value; }
}

To keep this tutorial from being too long, I’m not going to explain everything about this code. If you have questions about how these work, feel free to ask me, or do a little research and you’ll find plenty of sources that explain properties in depth.

The next bit we need to tackle is the constructor for this class. Following is the code for the constructor.

public AnimatedSprite(Texture2D texture, int currentFrame, int spriteWidth, int spriteHeight)
{
	this.spriteTexture = texture;
	this.currentFrame = currentFrame;
	this.spriteWidth = spriteWidth;
	this.spriteHeight = spriteHeight;
}

The constructor is basically just a method that initializes and creates instances of the data types that we create by creating a class. Each class that you create can be viewed as a new data type. The constructor’s parameters are often used as shortcuts for setting the values of the properties that you defined above the constructor.

In order to allow our sprite to move, we’ll want to check keyboard states to see which keys, if any, are currently pressed. At the top of the class, before the properties, and just before the variables that we declared earlier, we need two variables of type KeyboardState.

KeyboardState currentKBState;
KeyboardState previousKBState;

Now that we have variables created for storing keyboard states, lets utilize them and create a method to handle the movement of our sprite.

public void HandleSpriteMovement(GameTime gameTime)
{
	previousKBState = currentKBState;
	currentKBState = Keyboard.GetState();

	sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);

	if (currentKBState.GetPressedKeys().Length == 0)
	{
		if (currentFrame > 0 && currentFrame < 4)
		{
			currentFrame = 0;
		}
		if (currentFrame > 4 && currentFrame < 8)
		{
			currentFrame = 4;
		}
		if (currentFrame > 8 && currentFrame < 12)
		{
			currentFrame = 8;
		}
		if (currentFrame > 12 && currentFrame < 16)
		{
			currentFrame = 12;
		}
	}

	// This check is a little bit I threw in there to allow the character to sprint. It is completely optional.
	if (currentKBState.IsKeyDown(Keys.Space))
	{
		spriteSpeed = 3;
		interval = 100;
	}
	else
	{
		spriteSpeed = 2;
		interval = 200;
	}

	if (currentKBState.IsKeyDown(Keys.Right))
	{
		AnimateRight(gameTime);
		if (position.X < 780)
		{
			position.X += spriteSpeed;
		}
	}

	if (currentKBState.IsKeyDown(Keys.Left))
	{
		AnimateLeft(gameTime);
		if (position.X > 20)
		{
			position.X -= spriteSpeed;
		}
	}

	if (currentKBState.IsKeyDown(Keys.Down))
	{
		AnimateDown(gameTime);
		if (position.Y < 575)
		{
			position.Y += spriteSpeed;
		}
	}

	if (currentKBState.IsKeyDown(Keys.Up))
	{
		AnimateUp(gameTime);
		if (position.Y > 25)
		{
			position.Y -= spriteSpeed;
		}
	}
}

The code above might look like a lot, but it isn’t. It first checks to see if any keys are currently pressed. If no keys are pressed, then it checks to see what the current frame of the animation is and sets the frame to the start of that particular walk cycle so that it looks like the character stopped walking and returned to a resting position. Then we check to see which keys are pressed, the sprint section is completely optional and it’s just something I threw in there because I like to have the option to be able to move faster when I feel like it, if up, down, left, or right are pressed then we animate the sprite by calling the appropriate method that we will get to in just a few minutes, and as long as our sprite isn’t hitting the boundaries of the screen, which is where those magic numbers in the if checks came from, then we apply the speed to the position of the sprite moving in the appropriate direction.

Alright, it’s time to move to the actual methods that create the animation of the sprite and moves from one frame to another. To accomplish this, we use the following code:

public void AnimateRight(GameTime gameTime)
{
	if (currentKBState != previousKBState)
	{
		currentFrame = 9;
	}

	timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

	if (timer > interval)
	{
		currentFrame++;
		
		if (currentFrame > 11)
		{
			currentFrame = 8;
		}
		timer = 0f;
	}
}

Above is the code for the AnimateRight() method. The other three methods that we will create in a minute are just the same, except they deal with the proper frames inside our sprite sheet for moving up, down, and left. After we change the current frame, the timer is reset and continues to increment. Following is the code for the AnimateLeft(), AnimateUp(), and AnimateDown() methods. I’m not going to go through and explain each one, since you should be able to figure out what each of them do just by reading the explanation of the AnimateRight() method from above.

public void AnimateUp(GameTime gameTime)
        {
            if (currentKBState != previousKBState)
            {
                currentFrame = 13;
            }

            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            if (timer > interval)
            {
                currentFrame++;

                if (currentFrame > 15)
                {
                    currentFrame = 12;
                }
                timer = 0f;
            }
        }

        public void AnimateDown(GameTime gameTime)
        {
            if (currentKBState != previousKBState)
            {
                currentFrame = 1;
            }

            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            if (timer > interval)
            {
                currentFrame++;

                if (currentFrame > 3)
                {
                    currentFrame = 0;
                }
                timer = 0f;
            }
        }

        public void AnimateLeft(GameTime gameTime)
        {
            if (currentKBState != previousKBState)
            {
                currentFrame = 5;
            }

            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            if (timer > interval)
            {
                currentFrame++;

                if (currentFrame > 7)
                {
                    currentFrame = 4;
                }
                timer = 0f;
            }
        }

From here we’ll open the Game1.cs class. At the top of the class, under the SpriteBatch declaration, we’ll need to declare a variable of the type we just created.

AimatedSprite sprite;

Inside the constructor for the Game1 class, you’ll need to set the PreferredBackBufferWidth and PreferredBackBufferHeight to the desired settings. Below is the code for the Game1 constructor.

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

        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 600;
}

Now move down to the LoadContent() method and create a new instance for our spriteBatch.

spriteBatch = new SpriteBatch(GraphicsDevice);

We also need to create an instance for our sprite, sprite = new AnimatedSprite(Content.Load(“Sprite_Sheet”), 1, 32, 48);. We also need to determine the starting position of our sprite, sprite.Position = new Vector2(400, 300);. I chose to start the sprite in the middle of the screen. 400 x 300 is the center of the screen as long as XNA is rendering to a window with the default size of 800 x 600. You can change the values inside the parenthesis if you want your sprite to start elsewhere. Following is the entire code for the LoadContent method just incase I was a bit confusing with the above paragraph:

protected override void LoadContent()
{

	spriteBatch = new SpriteBatch(GraphicsDevice);

	sprite = new AnimatedSprite(Content.Load<Texture2D>("Sprite_Sheet"), 1, 32, 48);

	sprite.Position = new Vector2(400, 300);
}

The next place we need to add code is the Update method of the Game1 class. This will just be a single line, which can be placed at the top of the method just inside the brackets.

sprite.HandleSpriteMovement(gameTime);

This call in the update method will call our HandleSpriteMovement method from the AnimatedSprite class that we wrote earlier. Each time the game is updated, this method will be called and the logic inside it will be performed. If you only want the sprite to animate at certain times, for instance when the game is not paused, then you can throw that call inside an if check inside the update method.

The only real thing left to do is add a few lines to our draw method to draw the sprite to the screen. Following is the entire code for the draw method:

protected override void Draw(GameTime gameTime)
{
        // I don’t like looking at the default CornflowerBlue color
GraphicsDevice.Clear(Color.DarkOliveGreen);

            spriteBatch.Begin();
            spriteBatch.Draw(sprite.Texture, sprite.Position, sprite.SourceRect, Color.White, 0f, sprite.Origin, 2.0f, SpriteEffects.None, 0);
            spriteBatch.End();

            base.Draw(gameTime);
}

The code within the draw method is pretty simple, we tell the spritebatch to start and then we tell it to draw our sprite using the texture, position, rectangle, color, rotation, origin, scale, sprite effects, and layer depth. I won’t go into detail about sprite effects or layer depth because that’s beyond what this tutorial is supposed to cover. Finally, we tell the spritebatch to end.

And that’s it! That’s all it takes to animate a simple sprite sheet. If you have any questions, or want me to explain anything a little better, feel free to let me know.

The start of something great! (Hopefully)

This blog is something that I threw together because of something that I’ve wanted to do for a long time, but just haven’t gotten around to doing it until now. Basically this blog is just going to be a place where I post my thoughts on XNA, game development, C#, and possibly life in general. For starters, I’m going to start with some simple XNA tutorials and walkthroughs which will eventually culminate in a project where we will create a complete 16-bit styled role-playing game such as those from the glory days of gaming. The biggest inspiration for this project is going to be Final Fantasy VI, since this is still my favorite game of all time. Other inspirations will include Breath of Fire, Chrono Trigger, Bahamut Lagoon, and just about any other RPG from the 80s and 90s that I grew up with. We’ll begin with something simple, and slowly work our way through more complex processes and code including building an entire tile map engine with a nice WinForm editor that will be heavily influenced by Nick Gravelyn’s Tile Engine Tutorial series, but that will be a long ways down the road. I guess all that’s left to say now is welcome to the site, have a seat, make yourself comfortable, and get ready to learn something.