I’ve been working on Sprite Animation a lot in my home engine (a post about it is incoming). I thought I’d take the time to explain where I began and where I ended up.
During my first iteration of the engine I had a completely separate component than SpriteComponent for animating things. It was inventively called AnimatedSpriteComponent. This would form the basis of my later implementations, but it had some pretty serious drawbacks. One of which was that making an animated sprite with this method meant you would have a different sprite for every single animation you wanted to have. This would be pretty wasteful, and would get really annoying trying to juggle the animations on and off at the correct times.
On my second (and current) engine iteration I began doing things a little differently. I decided to make all sprites animated by default. They could be passed some optional parameters on creation that would give the relevant animation info. This had a similar drawback to the first iteration, where each sprite could only have one animation that was either on or off. This would make it cumbersome to use. Also it took different textures for each frame, which is a big no-no as switching textures is really expensive, so all frames for an animation should rightfully be in one texture.
The most recent improvement to this system came with the introduction of a middle-man between Texture and Sprite – Images. This is also when I introduced support for Texture Atlases. Images are essentially a way to pick a single picture out of a big texture packed with a lot of different ones. Images made it so I didn’t have to have different textures for each animation frame, I just had an Image for each instead.
My second improvement was making animation something the sprite class had no active hand in. Up till now all animation has been done in the SpriteComponents Update method. I decided to take the animation functionality out of SpriteComponent and made a new class out of it – AnimationClip. Now each Sprite has a collection of AnimationClips which are referenced by their names. AnimationClips can take a start frame and a number of frames, which they will then attempt to load in order.
E.g. spriteComponent->AddAnimation(“animationName”, 6, “testAnimFrame”);
It will then attempt to load testAnim1, testAnim2,…testAnim6. Alternatively you can just supply a list of as many frames as you want.
E.g. spriteComponent->AddAnimation(“animationName”, 5, “testAnimFrame1”, “testAnimFrame2”, “testAnimFrame3”, “differentTestAnimFrame4”, “testAnimFrame5”);
You’re then able to reference these animations in an easy way:
That’s pretty much where I am now. I’m pretty happy with my current system but there are definite improvements to be made. Right now a Sprite will just play whatever it’s active animation is if it has one. I’d like to add both default animations, and triggerable animations. So you can set a sprites default animation, and it will play that one whenever it doesn’t have anything else to play. This will make the introduction of triggerable animations easy, as they will just play for however long you want before transitioning back to the default.
Also it’d be cool if you could set event callbacks at specific points during the sprites animation, so you could, for example, set up the sound of a footstep to play each time a character took a step. ALSO it’d be nice if the timeline of animations worked in such a way that you could play them backwards by just specifying a negative speed.
I guess what I’ve discovered is that sprite animation is a very interesting thing to work on, I can see myself being distracted by it for quite a while.