2D Skeletal Animations

What is your preferred way of doing animations in 2D?

Most of you will probably answer “spritesheets”, and you’d be right. Creating animations using spritesheets is quick, easy, there are helpful resources on the net and if you work with an external artist, he only needs to give you the individual frames of the animation (which also makes his life easy).

You would want to have a framerate of at least 12 for your animations, and you soon end up with something like this:

Example Animation

And with minimal effort, you can write code that loads this and displays it as an animation [SpriteSheetAnimation.zip]

All is well in the world, until you realize your game needs LOTS of animations and the memory consumption goes way up, together with the time required to load all the data. Also, to limit the size, you need to limit yourself to a low FPS for the animation (like 12), which also means the animation doesn’t look as smooth as you’d like. This is where skeletal animation comes in.

When using skeletal animation, the animation is composed of several bones which are connected to one another. Affecting a bone also affects all of its children. By composing different transformations on each bone, you obtain different poses for the skeleton.

Now, if you define keyframes with certain transformations for a point in time for each of the bones in the skeleton, you can interpolate between the keyframes to obtain a smooth transition and thus animate the skeleton.

In the attached code, I used a class named Transformation, which contains data about 2D transformations, like translation, rotation and scale. Then, a Keyframe is defined by a frame number and one such Transformation. A collection of Keyframes defines a KeyframeAnimation. Finally, a SkeletonAnimation is a collection of KeyframeAnimations, one for each bone in the skeleton.

Separately, I use a Skeleton, which keeps a list of Joints that define the hierarchy of bones in the skeleton. Each bone is then assigned a certain texture, like the ones below:

machine_armmachine_forearmmachine_hookLeftmachine_hookRight

Each of the parts are individually animated relative to their parent bone, and thus the animation is obtained. In the sample, the animation is stored in two XML files that are loaded directly into a Skeleton (see machine_skeleton.xml ) and a SkeletonAnimation (see machine_animation.xml ) using the ContentPipeline at runtime. Here’s a video of the sample using skeleton animation:

As you can see, it runs much smoother than the initial frame-based animation. Also, looking at the resources used, the amount of texture data loaded into memory is significantly reduced (from 5.12 Mb to only 73Kb).

A word on how the XML file was generated. There are multiple options here.

  • make a tool for editing animations, where you would set-up the positions of each frame and serialize it to disk using the IntermediateSerializer.
  • let your artist create the animation in a software of is choice that can output the keyframes to XML, and then write a small program that converts that XML in the suitable format to be loaded by the Content Pipeline. For the animation above, I used a Flash animation created by a friend, exported the keyframes to ActionScript3 XML, and then converted that XML into the one you can see in the sample. (I won’t release that mini-tool however, since its code is a mess thrown together in about 1 hour).

A word of warning: while skeletal animation helps solve some problems with memory, loading times, smoothness, it is not a silver bullet. The amount of detail that can go into a normal sprite-sheet animation far surpasses what can be done with a skeletal animation. In skeletal animations you are limited to certain transformations on each ‘piece’ of the animation: translate, rotate, scale, flip. Meanwhile, frame-based animation allows the artist to add any kind of effect he likes.

I hope you enjoyed this sample. Feel free to leave any feedback and questions below.

To get the code, either download it directly (SkeletalAnimation.zip) or go to the sample’s page.

Until next time,

Happy coding!

  • http://Website M

    Having gone down this route myself, I would recommend AGAINST IT. Check out how Maya was used to create Mika Mobile’s Zombieville game.

    http://www.thecareergamer.com/braaaains-zombieville-usa-tech-review/

    I would recommend using 3D even for 2D so you don’t need to code your own editor and the artists can use off the shelf tools for most of their work.

  • http://x35mm.wordpress.com x35mm

    Keyframed animation is the best thing I’ve added into my game so far. As a one-man team, I would never have enough time to create a spritesheet of animations, and by using silhouette-style art ala Limbo/Patapon, you can really cheat on the animations as you’re only concerned with the outlines 😉

  • http://www.thirdpartyninjas.com Jesse Chounard

    Neat. I wrote a tool to create 2d skeletal animations, myself. (There’s also some code for loading them up into XNA games.) It’s been used in a few games so far.

    http://demina.codeplex.com/

    Also, there’s no reason you can’t mix spritesheet and skeletal animations. (Demina supports that, though you can’t start with premade spritesheets.)

  • Catalin Zima


    M:

    Having gone down this route myself, I would recommend AGAINST IT. Check out how Maya was used to create Mika Mobile’s Zombieville game.

    http://www.thecareergamer.com/braaaains-zombieville-usa-tech-review/

    I would recommend using 3D even for 2D so you don’t need to code your own editor and the artists can use off the shelf tools for most of their work.

    Using Maya to create a 3D animation that you later import in your game is no different then one of my suggestions of using a tool that the artist is familiar with and exporting from that tool in a proper format.
    In Chickens Can’t Fly, our artist uses AfterEffect or Flash (which I might say are ‘off the shelf’ tools 😉 ) to compose animations and all sort of special effects. Then we have some scripts we run to convert the animation into a properly formatted XML file that we can load directly in our game.

    This means that artists can use his choice of tools, and we can use skeletal animation just fine without writing an editor.

  • Catalin Zima


    Jesse Chounard:

    Also, there’s no reason you can’t mix spritesheet and skeletal animations. (Demina supports that, though you can’t start with premade spritesheets.)

    Quite true. In our ‘production’ system, we combine spritesheets and skeletal animations when needed, so some animations are classic spritesheets, with lots of details and stuff that couldn’t be handled by skeletons, and whenever we can use skeletal animation, we do so.

  • Pingback: Catalin on 2D Skeletal Animations « Sgt. Conker

  • Pingback: Kinect SDK/iphone dev/web dev/algorithm/.net/and more… | CactuarJ's NotePad

  • Pingback: Windows Client Developer Roundup 073 for 6/19/2011 - Pete Brown's 10rem.net

  • http://offbeat-games.com/ Erik Skoglund

    Very nice. The game I’m making is using a similar approach. This also makes it easy to integrate scripting with the animations, playing sounds at certain keyframes etc. I’ve found that it’s a lot quicker, especially if you’re not a great artist, to do these kind of animations.

  • http://www.gnomicstudios.com Aranda Morrison

    Catalin, nice sample. You wouldn’t care to share some of the “scripts we run to convert the [flash] animation into a properly formatted XML file”? This approach is definitely the way forward.

  • http://www.gnomicstudios.com Aranda Morrison

    I just re-read the section where you said you wouldn’t release it. Personally I don’t mind messy code, at least it’s a place to start from 🙂

  • Catalin Zima

    The script that converts the AfterEffects animations into skeletal animations was developed inside Evozon and is company property, so I can’t release that.
    However, I’ll try to look into releasing the code I used for the Flash animations, which belongs to the prototype I developed at home. It’s mostly just XML conversion and is a rather manual process, but I’ll see what I can do.

  • http://www.gnomicstudios.com Aranda Morrison

    Ok, I thought you’d be exporting all the animation data right from Flash, which I’m sure is possible. I think Super Meat Boys guys have an exporter which does sprite sheets AND animation data, which pretty awesome. Anyway, when you do release any code, it’s always much appreciated!

  • http://Website Kim

    Thank you for this very interesting post. I have been looking for something like this for some time.

    I have previously worked with flash and have some experience with keyframe animation. So, I downloaded the trial version of Flash CS5 and started to create a basic animation to test. I got that done but I have not figured out yet how to export keyframes to XML. Would you mind explaining how you did that?

  • http://is.gd/hhv8Ea Hayden

    I want nothing more but circles all around. I love the shape. I’m not quite good at 2D or animation in general; but darn I’m trying so hard. Argh! Any tips peeps? Gladly appreciate if you will.

  • http://www.webdesignmilwaukee.co/about/ Gary

    Thanks for sharing this code – now time to sit down and get to working with it.

  • Pingback: best 3d software

  • Pingback: consultoria de sistemas

  • http://www.systec-services.com Tim Stern

    Hi Catalin,

    I discovered a possible mistake in your file Transformation.cs, function public Vector2 TransformPoint(Vector2 point).

    You have to scale the point bevore transforming it with the rotated matrix.

    The code will then be like that:
    Vector2 result = Vector2.Transform(point * Scale, Matrix.CreateRotationZ(Rotation));
    // result *= Scale; // is wrong here!
    result += Position;
    return result;

    Kind regards from Germany,
    Tim

  • Pingback: De leukste filmpjes gratis plaatsen en bekijken.

  • Pingback: 2d Skeletal animation implementation from flash to Cocos2d

  • Pingback: shopping

  • Catalin Zima

    Thanks, Tim

  • http://ibpoe-of-w.org/coppermine/displayimage.php?album=1&pos=1 list

    Asking questions are genuinely pleasant thing if you are not understanding
    something totally, however this article provides fastidious understanding even.

  • http://tinyurl.com/tomaalt14734 http://tinyurl.com/tomaalt14734

    I personally Think that blog post, “Catalin’s Game Development Blog » 2D Skeletal Animations” was in fact fantastic! I reallycan’t agree along
    with u even more! At last seems like I reallycame across a website worth reading.
    Thanks, Iris

  • http://www.journalhome.com/erikajqbmy/387515/zbowl-coupons-working-coupons.html zbowl

    I am genuinely pleased to glance at this webpage posts which consists
    of tons of useful information, thanks for
    providing these kinds of information.

  • http://www.23hq.com/joylindseyjxfd/story/12016606 bvlgari coupon codes

    I like it whenever people come together and share thoughts.
    Great website, continue the good work!

  • http://www.easiergame.com/monster-legends-cheats/ Monster legends cheats

    The second Maradona goal wwas an incredible slalom tell you 5 Eglish
    defenders as well as the goalkeeper. However, strange things
    start happening: the boy sees tracks that appear
    to go from being coyolte to human; they see a strange human figure wearing coyote skins; and,
    if it later appears that they can hit this man using truck, alll thewy find can be a baby lamb covered in a
    very coyote skin. It lowered the whalpe towards the jubilant villagers then took to the sky here we are at iits cave inside mountains.

  • http://www.explanimate.com.au/ Porda

    Thanks for the blog. The information posted here is useful.

  • SurfingNerd

    yeah i am about the same issue. i am designing animated characters, where the characters can have different armor and different weapons, and different effects on them. however the decision is a race between low memory usage on the Skelletal solution and low CPU/GPU consumtion on the spritesheet side. off course, i have to do it as skelleton and render then all assets, but i can also combine both techniques: rendering the Spritesheet on the fly, and using the spritesheet to fast draw the animation. i am developing with monogame.