14
\$\begingroup\$

EDIT: To clarify what exactly my question is: is this a good way to handle animations / animation state in a game engine with the eye on content creation / management? What are the flaws in doing it this way and what would be an alternative way to do it? -- Though my answer got partially answered in the comments, as it seems to be the way to go.

I'm trying to handle animations in a 2D game engine hobby project, without hard-coding them. Hard coding animation states seems like a common but very strange phenomenon, to me.

A little background: I'm working with an entity system where components are bags of data and subsystems act upon them. I chose to use a polling system to update animation states.

With animation states I mean: "walking_left", "running_left", "walking_right", "shooting", ...

My idea to handle animations was to design it as a data driven model. Data could be stored in an xml file, a rdbms, ... And could be loaded at the start of a game / level/ ... This way you can easily edit animations and transitions without having to go change the code everywhere in your game.

As an example I made an xml draft of the data definitions I had in mind.

One very important piece of data would simply be the description of an animation. An animation would have a unique id (a descriptive name). It would hold a reference id to an image (the sprite sheet it uses, because different animations may use different sprite sheets). The frames per second to run the animation on. The "replay" here defines if an animation should be run once or infinitely. Then I defined a list of rectangles as frames.

<animation id='WIZARD_WALK_LEFT'>
    <image id='WIZARD_WALKING' />
    <fps>50</fps>
    <replay>true</replay>
    <frames>
        <rectangle>
            <x>0</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
        <rectangle>
            <x>45</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
    </frames>
</animation>

Animation data would be loaded and held in an animation resource pool and referenced by game entities that are using it. It would be treated as a resource like an image, a sound, a texture, ...

The second piece of data to define would be a state machine to handle animation states and transitions. This defines each state a game entity can be in, which states it can transition to and what triggers that state change.

This state machine would differ from entity to entity. Because a bird might have states "walking" and "flying" while a human would only have the state "walking". However it could be shared by different entities because multiple humans will probably have the same states (especially when you define some common NPCs like monsters, etc). Additionally an orc might have the same states as a human. Just to demonstrate that this state definition might be shared but only by a select group of game entities.

<state id='IDLE'>
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_LEFT'>
  <event trigger='LEFT_UP' goto='IDLE' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_RIGHT'>
  <event trigger='RIGHT_UP' goto='IDLE' />
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
</state>

These states can be handled by a polling system. Each game tick it grabs the current state of a game entity and checks all triggers. If a condition is met it changes the entity's state to the "goto" state.

The last part I was struggling with was how to bind animation data and animation states to an entity. The most logical approach seemed to me to add a pointer to the state machine data an entity uses and to define for each state in that machine what animation it uses.

Here is an xml example how I would define the animation behavior and graphical representation of some common entities in a game, by addressing animation state and animation data id. Note that both "wizard" and "orc" have the same animation states but a different animation. Also, a different animation could mean a different sprite sheet, or even a different sequence of animations (an animation could be longer or shorter).

<entity name="wizard">
    <state id="IDLE" animation="WIZARD_IDLE" />
    <state id="MOVING_LEFT" animation="WIZARD_WALK_LEFT" />
</entity>

<entity name="orc">
    <state id="IDLE" animation="ORC_IDLE" />
    <state id="MOVING_LEFT" animation="ORC_WALK_LEFT" />
</entity>

When the entity is being created it would add a list of states with state machine data and an animation data reference.

In the future I would use the entity system to build whole entities by defining components in a similar xml format.

--

This is what I have come up with after some research. However I had some trouble getting my head around it, so I was hoping for some feedback. Is there something here what doesn't make sense, or is there a better way to handle these things? I grasped the idea of iterating through frames but I'm having trouble to take it a step further and this is my attempt to do that.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ I have come up with a similar idea for storing animation data, although I have not considered the triggers. Here's a short article I wrote about it and a link to an XNA project I wrote that consumes the XML and handles the animation side of things. I have a few things that are different, like the concept of Sets and Sequences, but other than that, I think you are on track. \$\endgroup\$ Commented Apr 9, 2012 at 18:57
  • 2
    \$\begingroup\$ Not that your design is bad (it's not, it's very much along the lines of a similar system I built in times past), but what exactly is your question here? I think it could really stand to be clearer. \$\endgroup\$
    – MrCranky
    Commented Apr 9, 2012 at 19:05
  • \$\begingroup\$ @ John - Thanks mate, I'll take a look at it later this evening. @ MrCranky - Well, mostly just what you said. If it's any good and possibly tips / links to more established methods. I'm really in the dark here experience-wise. \$\endgroup\$
    – user8363
    Commented Apr 9, 2012 at 19:29
  • 1
    \$\begingroup\$ I'd like to give this an upvote for the depth of information provided but, to echo MrCranky, I'm not really following what the question is. For my own personal advice (which spawns from having built this kind of system a couple weeks back) I'd say you're spot on. \$\endgroup\$
    – Mike Cluck
    Commented Apr 10, 2012 at 1:39
  • \$\begingroup\$ @MikeC That's just the answer I needed. I apologize for the fact I wasn't able to be clearer on my question. Maybe if I wasn't spot on it would look more like a question :). Fact is I couldn't find many resources that dealt with animation states and the ones that did hard-coded it so creating/changing content would be a nightmare. So my question is: is this approach right or not? And if you guys say it is, then that's fine :). \$\endgroup\$
    – user8363
    Commented Apr 10, 2012 at 8:44

2 Answers 2

4
\$\begingroup\$

Animation clips are best described in plain-old-data, as you've done in your first XML snippet. You can make this by hand, or export to it from an art package. Either way, you're probably going to want to create a pipeline that takes it from a human-readable intermediate format like XML and puts it into something that's nice and quick to load.

The next step is being able to render the thing. If you're using some sort of scene graph, that'll probably mean making an Anim Node for it. You should be able to tell the anim node which animation it is currently playing, and where in the timeline it currently is. Make sure that you keep bounding box information accessible at this level so that you can easily feed it into your culling system.

Now, you're going to want to associate an animation with a game entity. I tend to use a component-based model, so for me this means and AnimState component. This is your intermediate layer between gameplay and rendering. It keeps track of which animation an entity is playing, playmodes (looping, once, ping-pong, etc), timing, etc. It can send events like "animover" back to the entity, and updates the state of the animnode when appropriate. AnimStates for active entities will get updated once per sim tick if they are playing an animation.

An animstate component is probably enough for simple game items (basic background props and the like), but for more complicated entities you are going to want to use a state machine t o mange it. This is best expressed in a scripting language like Lua or Python. A state can have several functional blocks (onEnter, onExit, onUpdate, onEvent), as well as a timeline that specifies certain actions and triggers that should happen at certain times. You will probably have some kind of manager class that is responsible for updating these state machines as appropriate, as well as triggering the timeline callbacks when they occur. You should try to keep these things as event-based as possible, since every OnUpdate you write will be a linear cost with entity count. You're also going to want to be able specify tags ('attacking', 'idle', 'ignoreinput', etc) that are associated with both whole states and certain time regions of states. You'll probably also want some high-level event handlers that apply to the entire state-graph, and not just a particular state.

'Sentient' characters will probably have some kind of an AI as well. I tend to make a specific 'locomotor' component that handles walking around. It interfaces with the stategraph using a system of signals and events and querying for state-tags, and can be told to "walk to point", or "run in a certain direction at a certain speed". Higher-level AI components (like a behaviour tree or whatever) can then use this interface without worrying about the details.

\$\endgroup\$
1
\$\begingroup\$

The best data-driven animation system I've seen so far is the Blend Tree. Really, it's damn good and it can do all you're asking for here. According to AIGameDev.com it's now the de-facto standard in the industry, and I believe they're right.

Unfortunately I found no good resource with a quick googling, but you can try this or that to get an overview. There's also a paying article on AIGameDev.com, don't know if it's worth getting a premium account.

\$\endgroup\$
2
  • \$\begingroup\$ This is a very good resource, thank you. I'm looking for information like this. \$\endgroup\$
    – user8363
    Commented Apr 17, 2012 at 21:17
  • 1
    \$\begingroup\$ Blending animations is not possible with discrete sprite-sheets, only with continuous skeletal animation \$\endgroup\$
    – Alex
    Commented Feb 12, 2013 at 17:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .