Dragons and Dancing Crabs

Creating smooth animations in MonoGame using Spine

For those of you who don’t want to read the entire blog post (shame on you), here’s a slightly slowed down video of some animation in MonoGame using Spine to create the animation. In summary, this can be achieved with just a few lines of code in MonoGame.

Introduction

This blog post is a guide to producing smooth animation in MonoGame using Inkscape, TexturePacker and Spine. Below is a ‘short and simple beginner level’ introduction to each of these apps and then a slightly more detailed step by step tutorial for getting an animation up and running in MonoGame.

Inkscape


Inkscape is an Open Source scalable vector graphics editor – similar to Illustrator or CorelDraw, but completely free of charge. You don’t need to be pay loads of money to produce good vector graphics, but you do need to be able to draw. If you can’t draw then it doesn’t matter how much money you spend on an app, it won’t make you suddenly produce better graphics.
I hadn’t used any vector graphics editing software before so Inkscape seemed a good choice – it was free so if I didn’t get on with vector graphics editing then I hadn’t wasted any money.

TexturePacker


TexturePacker is a neat tool for producing ‘sprite sheets’. Once you’ve created all your separate image files for your game (e.g. using Inkscape), you simply drag and drop them into TexturePacker which then exports one large image file along with a data file describing where each individual image is within the larger image. Using sprite sheet is more efficient than loading lots of individual images in game development. (See Wikipedia for more info).

Spine


Approximately a month ago I heard about a Kickstarter project from Esoteric Software to make Spine – an application that allows you to make 2D skeletal animation for games. Taken from their web-site…

“…Spine replaces traditional raster animation in games, providing smoother animations that are easier to produce. Animations can be created without needing more art and are so tiny that games can make extensive use of them…

So I backed the project and now have a working copy of the Spine app running on my mac – and it is pretty good! In my opinion anyone who needs to animate any kind of character (or title screen for that matter) should buy it. It will save you so much time! Note: Spine is also available for windows.

MonoGame


MonoGame is an Open Source implementation of the Microsoft XNA 4 Framework. As a MonoGame Evangelist’ I will be biased of course, however even so, it is awesome! 🙂 Develop an app using MonoGame and with a few device specific changes you can target lots of different platforms with a huge percentage of shared code.

Tutorial

That’s the introduction out the way, so let’s start creating our animation!
Note: All the code and graphics are available on github.

Step 1 – Inkscape – Creating our graphics


I decided to try out a vector based graphics application for my next game so that it would be easier to produce graphics for various screen sizes (e.g. iPad v iPad retina). i.e. I could just draw one set of graphics and then scale the vector diagram appropriately before exporting the png/jpg file.

Note: You don’t have to use a vector graphics editor for producing your images to use in Spine or MonoGame. Any graphics tool that produces images is fine. I simply wanted to try out a vector graphics editor, as I hadn’t used one before.

If you haven’t used Inkscape before then I’d recommend you follow the tutorials in the first few chapters here. It’s fair to say that Inkscape is pretty powerful, but if creating vector graphics is new to you then you will have to put some effort in to avoid frustration. I also found that the 2D Game Art for Programmers site was a useful learning resource.

So traditionally when creating graphics you might have an image of your character in one position and then another image in the next position and so on – e.g. one image with both feet together – another with left foot forward and then one with the right foot forward. This is fine, however it would be nice to make animations where each limb moved smoothly – hence this tutorial.

One of the main characters in my next game is going to be a crab, so I’ve drawn a simple crab, as below, using Inkscape.

InkscapeCrab

Now, rather than exporting this entire picture as a single image, I have exported each ‘movable part’ as separate images – The intention being that we want to animate each body part separately to create realistic motion – hence we need separate body part images. Fortunately Inkscape allows you to export individual shapes/paths of an image to a bitmap/png/etc file – as shown below.

InkscapeExportSelectionCrab

The only problem however is that it actually exports the square selection surrounding all selected images rather than the actual selection – therefore you need to move the selected body part to a blank section of the page, then export the selection and then undo the move so that it goes back to the correct location. Repeat this for each body part and you will end up with a series of images files – one for each movable body part.
Note, it is worth giving some thought to how you name your images files to make it easier to identify them later – e.g. BackUpperLegLeft.

Step 2 – TexturePacker

Now we have all our individual images files we need to load them into TexturePacker to create our Sprite Sheet. This part is very easy.

  • Open TexturePacker
  • Drag and drop each individual image file into TexturePacker
  • Ensure the Data Format is set to “JSON (Array)”
  • Ensure “Trim Mode” is set to ‘none’
  • Press Publish to create a Json data file and a PNG Sprite Sheet

You should now end up with a Json file looking something like this…

{"frames": [

{
	"filename": "BackLowerLegLeft.png",
	"frame": {"x":294,"y":335,"w":36,"h":69},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":36,"h":69},
	"sourceSize": {"w":36,"h":69}
},
{
	"filename": "BackLowerLegRight.png",
	"frame": {"x":285,"y":407,"w":36,"h":69},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":36,"h":69},
	"sourceSize": {"w":36,"h":69}
},

…and a SpriteSheet looking something like this…

TexturePackerCrabSpriteSheet

Step 3 – Spine

Right, we’ve done the easy bit – now for the fun part! Creating our animation…

At this point I would suggest you go to the Esoteric Software web-site and watch the “Quick Overview Part 1” and “Quick Overview Part 2” videos. They are both approximately 10 minutes in length. They will tell you enough for you to create an animation in Spine. But in summary, you will need to export a copy of the entire crab from Inkscape and import this as your template image in Spine so you can line everything up – then draw the ‘bone structure’ on top of this template – then apply the individual images to each bone – delete the original template file and then you can start creating an animation by rotating each bone/image on various frames of the timeline. Spine will then take care of ensuring a smooth animation between each frame. Below we can see the ‘bone structure’ I have created for the crab.

SpineCrabBoneStructure

One thing you may notice is that there are ‘bones’ for the two eyes and eye-lids. The reason for this is that I am going to make the eye and eye-lid jump up in the air in a cartoon style. So, don’t necessarily think of ‘bones’ as having to mirror where real bones are – instead it is all about what parts of the animation need to move. Further to this, if I had wanted the teeth to move about then one approach would be to create separate teeth images instead of them being part of the head image – then I could have created ‘bones’ to attach them to and animated them.

Something else you may have noticed earlier is the additional eyes in the Sprite Sheet exported by TexturePacker. We have one set for looking forwards, where the pupil is in the middle of the eye – and another set for looking to the side where the pupil is on the side of the eye. The reason for this is because we can still use ‘old fashioned style’ animation where required – i.e. When creating our crab skeleton in Spine we can attach both types of eye images to the ‘eye bone’ but choose on a per frame basis which one we want to use. Thus, when the crab walks to the side he can look to the side, but when he is stood still he can look forwards.

Once you’ve completed your animation within Spine you’ll need to export a Json file of your work. (Select the ‘export’ menu option – ensure Json is the selected data format – select a destination – and press ‘Export’. This will create a Json file containing the basic skeleton structure of your character and all the animations.

Step 4 – Putting it all together

At this stage we have the following…

  • Our Sprite Sheet [produced by TexturePacker]
  • A Json file describing the details of the individual images within the Sprite Sheet [produced by TexturePacker]
  • A Json skeleton file [produced by Spine]

We now need to work out how to put this all together to create animations within MonoGame…

On the face of it this may sound quite tricky. Although writing code to import the Sprite Sheet and parse the Sprite Sheet Json data file is relatively simple, writing code to import the Spine animation data and then understand that data to perform the animation is quite complex. Fortunately Spine offers more than creating the animation – The guys at Esoteric Software have also created some run-times for different platforms which you can plug into your own code. They have a runtime for LIBGDX (in java) and another for Corona (in LUA).

But wait, how does that help us? We need a c# MonoGame runtime.

Now, one of the stretch goals for the Spine Kickstarter was to develop a generic c# runtime. The good news is that this stretch goal has been reached and is due to be developed within the next few weeks, however I couldn’t wait that long so I decided to try writing my own runtime specifically for MonoGame. 🙂
Now, I must point out that although I do indeed have a runtime which is available for anyone to use, I don’t really feel I can take a huge amount of credit for it because it is entirely based upon the work already done by the guys at Esoteric Software – i.e. heavily based on the LIBGDX and Corona runtimes.

So, the source code for the MonoGame runtime can be found on GitHub. Grab a copy of this and you will see a ‘runtime project’ and an iOS ‘demo project’. Add a reference to MonoGame and it will build and you’ll see an animated crab.
Note: If you want to run this on a different platform than iOS then just create a new runtime project (for your platform) and add all the source files. Then implement an equivalent demo project.

If we look at the code needed to create an animation then it is pretty simple! Below is our entire Game class for rendering a smooth animation. The key parts are…

  • The LoadContent method where we (a) load our TexturePacker SpriteSheet and (b) load our Spine skeleton Json file.
  • The Draw method where we move the animation along based on the time and then simply call ‘Draw’ on the skeleton passing in our SpriteBatch and letting the Spine runtime take care of the rendering.

Simples!

/// <summary>
/// Animation demo.
/// 2013-March
/// </summary>
namespace Demo
{
	using Microsoft.Xna.Framework;
	using Microsoft.Xna.Framework.Graphics;
	using Microsoft.Xna.Framework.Input.Touch;
	using Spine.Runtime.MonoGame;
	using Spine.Runtime.MonoGame.Attachments;
	using Spine.Runtime.MonoGame.Graphics;
	using Spine.Runtime.MonoGame.Json;

	public class AnimationDemo : Game
	{
		private readonly GraphicsDeviceManager graphicsDeviceManager;
		private SpriteBatch spriteBatch;
		private Texture2D crabTextureMap;
		private Skeleton crabSkeleton;
		private Animation crabAnimationWalk;
		private float timer = 0;

		public AnimationDemo ()
		{
			this.graphicsDeviceManager = new GraphicsDeviceManager (this);
			this.graphicsDeviceManager.IsFullScreen = true;
			
			this.graphicsDeviceManager.SupportedOrientations = 
				DisplayOrientation.LandscapeLeft | 
					DisplayOrientation.LandscapeRight |
					DisplayOrientation.PortraitDown | 
					DisplayOrientation.Portrait;
			
			this.Content.RootDirectory = "Content";
		}
		
		protected override void Initialize ()
		{
			TouchPanel.EnabledGestures = GestureType.Tap;
			
			base.Initialize ();
		}

		protected override void LoadContent ()
		{
			// Load our sprite sheet
			this.crabTextureMap = Content.Load<Texture2D>("crab.png");
			var texturePackerReader = new TextureMapJsonReader ();			
			var spriteSheet = texturePackerReader.ReadTextureJsonFile("Content/crab.json", this.crabTextureMap);

			// Load our basic skeleton
			var skeletonReader = new SkeletonJsonReader(new TextureAtlasAttachmentLoader( spriteSheet));
			this.crabSkeleton = skeletonReader.ReadSkeletonJsonFile("Content/crab-skeleton.json");
			this.crabSkeleton.FlipY = true; // MonoGame origin is top left so we need to flip the y axis

			this.crabAnimationWalk = crabSkeleton.Data.FindAnimation ("WalkLeft");

			// Finally set the initial state/position of our crab
			crabSkeleton.SetToBindPose();
			
			var root = crabSkeleton.GetRootBone();
			root.X = 500;
			root.Y = 750;
			
			this.crabSkeleton.UpdateWorldTransform();

			this.spriteBatch = new SpriteBatch (this.graphicsDeviceManager.GraphicsDevice);

			base.LoadContent ();
		}

		protected override void Draw (GameTime gameTime)
		{
			this.spriteBatch.Begin ();

			this.GraphicsDevice.Clear (Color.CornflowerBlue);

			// In reality you'd probably pass in some time related variable to this rather than
			// my crude timer variable for demonstration purposes.
			// Also you'd probably want to perform the UpdateWorldTransform outside of the draw method
			// Should probably be in the Update method
			this.crabAnimationWalk.Apply(crabSkeleton, timer++ / 100, true);
			this.crabSkeleton.UpdateWorldTransform();
			this.crabSkeleton.Draw(this.spriteBatch);

			this.spriteBatch.End ();

			base.Draw (gameTime);
		}

		protected override void Dispose (bool disposing)
		{
			this.crabTextureMap.Dispose ();

			base.Dispose (disposing);
		}
	}
}

If you want to see this running on your machine then you can grab the source code from GitHub.

Where do we go from here…

Currently the structure of the MonoGame runtime code needs a bit of work. As stated, I cobbled it together by looking at the existing Corona and LIBGDX runtimes and just concentrated on getting something working. The code could do with a bit of refactoring in terms of encapsulation and general c# structure, however it works so it will do for now. There are probably a couple of features not yet implemented (colour blending for example) and I haven’t tried the mixing of animations or different skins yet. Also I believe you can export binary data, rather than Json, from Spine which will probably load quicker – however I haven’t written a binary importer yet.
I suspect I will actually wait until the official generic c# runtime is released and then fork that to create the next version of the MonoGame runtime. The advantage of this is that the core of the code will then be provided by Esoteric Software so any new features or bug fixes can just be taken from their fork – and I would imagine my MonoGame part of the code will be much smaller. However, it is a bit of an unknown at this stage – until the generic c# runtime is available we won’t know how well a MonoGame implementation might fit in – so worse case scenario is that I decide to keep my existing MonoGame runtime and maintain it. Either way, we can be sure that Spine animations will work with MonoGame!

At this point I feel I should also point out another option available to people. Trugnt has taken a fork of MonoGame and implemented loads of LIBGDX features within it. Their source is available on GitHub so gives people another option when it comes to implementing Spine and MonoGame together.

Enough with this crazy crab! Where’s the dragon?

Yes, there is a rather cool dragon in the video at the top of the page. If you want to see the graphics and Json files for that then you’ll need to download Spine from Esoteric Software and try them out yourself 🙂 Those graphics aren’t mine so I didn’t feel it was appropriate to include them in my demo project on GitHub. Consider it an exercise for the reader 🙂

Summary

So, in summary, if you want to create smooth animations for your games then I’d strongly recommend taking a look at Spine. I love it!
And if you use MonoGame to create your games then you now have the ability to use those animations in your MonoGame apps!

I hope this has been useful to you. Let me know how you get on.
Good luck and have fun!

EDIT: 04/04/2013 – Updated blog entry slightly to reflect recent change to the runtime as a result of a data format change in the latest version of Spine. The animation data is now included in the main skeleton Json file.

EDIT: 11/04/2013 – This is slightly out of date now because the official c# runtime has been produced by EsotericSoftware. See later blog post for more information.

Advertisements

4 thoughts on “Dragons and Dancing Crabs

    • Hi – thanks for your comment.
      The TextureMapJsonReader is old code. Actually this particular blog entry is old as well – there is a more recent blog post which I wrote after the official Esoteric XNA run-time was released. As such the code is a lot simpler and the TextureMapJsonReader disappeared. If you get the latest source from github then this should work straight away with the official Esoteric runtime. Let me know if you have any problems though.

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s