Inheritance-Based Sprite Management for XNA 4.0

My team recently won Best Game Award – 1st Prize at a “make a game in 32 hours” competition, and I thought I’d share the mini engine I wrote during this period to handle sprites.

Features

  • Easy to use and extensible inheritance-based object system
  • Animated sprite support
  • Camera-based sprite batch support
  • Automatic update/draw calls with manual overrides
  • Late drawing
  • Tag system for linking together sprites
  • Linear and Rotation velocity
  • Rectangle intersection test

Screenshot

Screenshot of the included sample.

License
The license is MIT.

Download
https://github.com/danielsefton/XNA-Sprite-Management

Usage

YourGame.cs:

public class YourGame : Microsoft.Xna.Framework.Game
{
	GraphicsDeviceManager graphics;
	SpriteBatch spriteBatch;
 
	SpriteManager spriteManager;
	Texture2D spriteTexture, animatedSpriteTexture, playerTexture;
 
	public GraphicsDeviceManager Graphics
	{
		get { return graphics; }
	}
 
	public YourGame()
	{
		graphics = new GraphicsDeviceManager(this);
		Content.RootDirectory = "Content";
 
		// Add the SpriteManager component.
		spriteManager = new SpriteManager(this);
		Components.Add(spriteManager);
	}
 
	protected override void LoadContent()
	{
		// Create a new SpriteBatch, which can be used to draw textures.
		spriteBatch = new SpriteBatch(GraphicsDevice);
 
		// Load the textures.
		spriteTexture = Content.Load<Texture2D>("TestSprite");
		animatedSpriteTexture = Content.Load<Texture2D>("TestAnimatedSprite");
		playerTexture = Content.Load<Texture2D>("TestPlayerSprite");
 
		// Create a standard sprite, rotated in code.
		Sprite sprite = spriteManager.CreateSprite("TestSprite", spriteTexture);
		sprite.Origin = new Vector2(spriteTexture.Width / 2, spriteTexture.Height / 2);
		sprite.Position = new Vector2(sprite.Origin.X + 100, sprite.Origin.Y + 100);
		sprite.RotationVelocity = 0.01f;
 
		// Create an animated sprite with a 6 frame sprite sheet.
		Sprite animatedSprite = spriteManager.CreateSprite(
			new AnimatedSprite("TestAnimatedSprite", animatedSpriteTexture, 6, 6));
		animatedSprite.Position = new Vector2(300, 100);
 
		// Create a controllable sprite. Notice the inheritance; a nice use of
		// polymorphism & encapsulation here.
		Sprite playerSprite = spriteManager.CreateSprite(
			new PlayerSprite("TestPlayerSprite", playerTexture, 6, 6));
		playerSprite.Position = new Vector2(500, 100);
		// Tags are a method for linking together one or more sprites.
		// Usage: spriteManager.GetSpriteWithTag("player");
		playerSprite.Tag = "player";
	}
}

PlayerSprite.cs – Example of custom sprite:

class PlayerSprite : AnimatedSprite
{
	private int speed = 3; // Player speed
 
	public PlayerSprite(String name, Texture2D texture, int frameCount, int framesPerSec)
		: base(name, texture, frameCount, framesPerSec)
	{
	}
 
	public sealed override void Update(GameTime gameTime)
	{
		base.Update(gameTime);
 
		// Set the bounds to the window width/height.
		Vector2 bounds = new Vector2(
			((Game1)SpriteManager.Game).Graphics.PreferredBackBufferWidth,
			((Game1)SpriteManager.Game).Graphics.PreferredBackBufferHeight);
 
		// Move the player with WASD.
		KeyboardState key1 = Keyboard.GetState();
		if (key1.IsKeyDown(Keys.D))
		{
			// Note: We must use Rect.Width here rather than Texture.Width, 
			// otherwise it will use the whole width of the sprite sheet.
			if (Position.X <= bounds.X - Rect.Width)
				Position.X += speed;
		}
		else if (key1.IsKeyDown(Keys.A))
		{
			if (Position.X >= 0)
				Position.X -= speed;
		}
		else if (key1.IsKeyDown(Keys.W))
		{
			if (Position.Y >= 0)
				Position.Y -= speed;
		}
		else if (key1.IsKeyDown(Keys.S))
		{
			if (Position.Y <= bounds.Y - Rect.Height)
				Position.Y += speed;
		}
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *