Sign in to follow this  

options for animating characters in 2D?

This topic is 3842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Greetings, I'm thinking of starting a project to build a 2D game, arcade style I suppose. It's not supposed to be any kind of realistic simulation, and in fact I much prefer games where the characters look like drawings/cartoons. Even so, I want them to move somewhat realistically, which involves walking, running, jumping, crouching etc. This isn't supposed to be anything big or fancy, so a simple working solution will do just fine. So far I've decided I'd like to use SDL. But it seems that SDL's idea of animation is a sequencing of sprites (is it?). I'm thinking this may not be such a good idea, animating each of the mentioned motions would probably be 10-20 frames, which not only is a lot to generate frames for, it sounds like it could be a performance problem. So what other techniques are there in the 2D world?

Share this post


Link to post
Share on other sites
I suppose there's a few ways to do this - but one way, that I've found to be quite efficient is this:

You have one bitmap for one sprite. The bitmap is divided into all frames for all the animations you want. For simplicity you might want to make all the frames the same size. So your sprite bitmap may be an image with the dimensions let's say 128x32, and one frame is 32x32 (I'm just picking some numbers here). In the simplest form, the FIRST 32x32 square in your bitmap (from (0,0) to (31,31)) may be frame 1. The second square in your bitmap may be frame 2 (from (32,0) to (63,31)) etc.

You may then want to have some sort of structure or class to store the frames of an animation. It could be something like:


typedef struct {
int frame_number;
double delay;
int next_frame;
} frame;


Where frame_number is the frame number in the bitmap like explained above. delay is how long this particular frame should be displayed. next_frame is the next frame in the animation obviously.

So now you got some place to store the frame data, you need some class to handle the animation. Example of such a class could be:

class Animation
{
private:
std::vector<frame> Frames;
int CurrentFrame;
double FrameDelayCounter;

public:
Animation();

void AddFrame(int framenumber, double delay, int next_frame);
void UpdateAnimation();
int GetCurrentFrame() { return Frames[CurrentFrame].frame_number; }
};


The class definition could be something like:

Animation::Animation() : CurrentFrame(0), FrameDelayCounter(0)
{
}

void Animation::AddFrame(int framenumber, double delay, int next_frame)
{
frame newframe;
newframe.frame_number = framenumber;
newframe.delay = delay;
newframe.next_frame = next_frame;

Frames.push_back(newframe);
}

void Animation::UpdateAnimation()
{
FrameDelayCounter += 1.0; //you may increase this counter with another number to get the animation to run quicker or slower
if (FrameDelayCounter >= Frames[CurrentFrame].delay)
{
CurrentFrame = Frames[CurrentFrame].next_frame;
FrameDelayCounter = 0;
}
}


Now... how to render just one part of the bitmap instead of the whole thing, so you only render the frame you want to render is a bit dependant on what your graphics API you are using (I'm afraid I can't help you with SDL). With OpenGL you can simply set the texture coordinates to match the rectangle that represents the current frame. Anyhow, here's at least a more generic function you could use parts of:


void Sprite::Render()
{
//assume that framewidth and frameheigth is set and that "animation" is an instance of the Animation class
int left = animation.GetCurrentFrame() * framewidth;
int right = animation.GetCurrentFrame() * framewidth + framewidth;
int top = animation.GetCurrentFrame() * frameheight + framewidth;
int bottom = animation.GetCurrentFrame() * frameheight;

/*
insert code here to render the area enclosed on the sprite's bitmap by the rectangle defined by the left, right, top and bottom variables
*/
}


I hope this helps you out a bit. I'm not saying this is THE best way to handle animations (and I'm only doing this on a hobby basis so I'm not a "professional", so kepe that it mind), but it certainly works. :)

Sorry for all the code, I'm bad at explaining properly by only using words. :)

Good luck.

Share this post


Link to post
Share on other sites
Thanks,

Your code is quite clear, and it seems to be the same thing I had in mind. It's the method suggested in LazyFoo's SDL tutorial (the only one I've looked at so far).

But my concern is that cycling say 25 frames/sec where each frame is maybe 40x80 pixels, might that be a performance issue? I don't really know anything about these multimedia libraries.

But coming back to animation, using this method implies I already have the sequence of images. If I want to have say 4 characters in my game, then I need to animate each one in every motion {walk, run, jump, crouch}, where each motion is maybe 20 frames. That's 4x4x20 images, with a lot of "duplication" (because every character is supposed to jump the same way and equally far, even though their appearance differs). So the issue I think begs for a programmatic solution.

Btw what would you use to animate these motions? Something like Blender?

Share this post


Link to post
Share on other sites
In my current project, characters are made of a number of sprites (head, torso, upper arm, forearm, hand, etc are all different sprites). I have those mapped onto a basic 2D skeleton which sets the orientation of each piece.

It takes longer to set up the system, but creating smooth animations is a cinch (it's similar to doing 3D animations, just minus 1D). It also lets you do automatic in-betweening and meshes nicely into a physics engine for ragdoll and procedural animation. And since it's just a skeletal system, similar characters can share animations.

Share this post


Link to post
Share on other sites
Quote:
Original post by JBourrie
In my current project, characters are made of a number of sprites (head, torso, upper arm, forearm, hand, etc are all different sprites). I have those mapped onto a basic 2D skeleton which sets the orientation of each piece.


Say do you happen to have any screenshots/videos of what that looks like in practice? I'm interested in how the meshes connect and form a whole compared to a drawing of the same character. Are there any "surface bugs" at the joints etc?

Also, how do you perform this animation, do you implement it or is it based on a library?

Quote:
Original post by JBourrie
It takes longer to set up the system, but creating smooth animations is a cinch (it's similar to doing 3D animations, just minus 1D). It also lets you do automatic in-betweening and meshes nicely into a physics engine for ragdoll and procedural animation. And since it's just a skeletal system, similar characters can share animations.


Hm, I've seen examples of ragdoll animations, but they were indeed ragdolls. How does that fit into animating an actual character? It seems you would have to add *a lot* of structure into that model to actual make it human motion.

Share this post


Link to post
Share on other sites
Quote:
Original post by maisnon
If I want to have say 4 characters in my game, then I need to animate each one in every motion {walk, run, jump, crouch}, where each motion is maybe 20 frames. That's 4x4x20 images, with a lot of "duplication" (because every character is supposed to jump the same way and equally far, even though their appearance differs). So the issue I think begs for a programmatic solution.


In a fast paced arcade game you need maybe something like 6 frames per motion. Really. Running and walking is very smooth with 8 frames, crouching and jumping maybe 3 or 4 etc. Twenty frames per motion is overkill, unless you plan to use some kind of slowdown effect. And if you plan your animation code correctly, you can easily add more frames to animations when you get the basics done.

I prefer hand drawn sprites and animations, but it would be a lot easier to use blender for characters that have lots of movements. And if you use blender or some other 3d-software, number of frames isn't really a problem, as long as you have enough memory for all of them.

Skeleton based animation is also one way to go, as suggested by JBourrie, but it really limits the appereance of your characters. And animations, since the motions are tied to 2d plane. This can be perfectly fine and even better than sprites if realistic physics are needed or if it goes with the style of the game (and its characters).

Share this post


Link to post
Share on other sites
Hand drawn frames
==================
takes more graphics space

Less processing.... just renders one big sprite

takes alot of time to hand draw all the frames

no artifacts at joints

flexibility to make characters face/twist/rotate etc

you can flip sprites to ge the other way

no artifacts as the parts of the sprite move



2D Skeleton
============
ideally you'll want an animation tool and an animator who can make the anims look cool

u only have to draw the character once, but he will always look to the side

you can switch on physics and rag-doll code when your characters get blasted

artifacts at joints (overlapping)

artifacts as you rotate the individual parts of the sprites

you can flip sprites to go the other way, but a little more work to flip the skeletal info

the animation will take up a little space, but will be less space than hand drawn frames

potentially less area/pixels to draw... Though more sprites in total.
so tt depends if you want to save drawing time, or processing time.

If there are lots of overlaps, then draw area could get worse rather than better.




so there are lots of advantages and disadvantages of both systems.
Just depends what you really need. Hope this helps.
Hand drawn is the typical method for nearly all 2D games.

A 3rd option is to build and animate the character in 3D, and render out the 2D frames. Then you get the best of both worlds (apart from ragdoll)
But you need 3D artist/animator

Share this post


Link to post
Share on other sites
Quote:
Original post by maisnon
Quote:
Original post by JBourrie
In my current project, characters are made of a number of sprites (head, torso, upper arm, forearm, hand, etc are all different sprites). I have those mapped onto a basic 2D skeleton which sets the orientation of each piece.


Say do you happen to have any screenshots/videos of what that looks like in practice? I'm interested in how the meshes connect and form a whole compared to a drawing of the same character. Are there any "surface bugs" at the joints etc?


I won't speak to the specifics of JBourrie's implimentation, but as far as looks go I imagine that this technique produces results similar to the Paper Mario games and many flash-based games found on the web as its the same, or a similar, technique.

It definately has a distinct visual style to it, which can be a good thing. Its not particularly well suited to very organic movement, as each limb/extremity is usually very stiff. I've always thought that it looks really increadible for mechanical things though; robots, mechs, machinery.


Another option is to base your game on vector graphics which, in its most basic form, is comprised of a 2D mesh rendered with simple filled polygons or lines. You can go further, implimenting all kinds of effects, but you begin to approach the point where you'd need to write it as an essentially full 3D system, simply constrained to two dimensions. This would give results similar to very polished flash animations.


As for the performance of bitmaps, I wouldn't worry about it too much. I have a software renderer at home that draws hundreds of thousands of 32bit, 32x32 tiles per second with clipping and transparancy on a 3Ghz P4, and its not even all that heavily optimized. Remember, that's *software* only, meaning that the CPU is doing all the drawing, I'm not even using the video card, which would be even faster.

There are some good practices though:

Keep sprites/level graphics in a single file like Ziggwarth described. At the very least its good for organization, and it will be neccessary for good performance if you ever port the game onto a 3D API later.

Keep these images (and the sub-images it contains) as powers-of-2 in size. This is very friendly to the computer and allows a lot of optimization to take place. It allows you to use shifts instead of multiplies(minor optimization) but most importantly it plays nicely with memory allocation, the CPU cache and with most 2D/3D APIs and hardware.

Keep It Simple! For many games a simple fixed-size partitioning scheme is perfectly adequate. This is again like Ziggwarth mentioned. Figure out what size images a particular image file will hold, then devide the whole into a regular grid where each sub-image fills a single sub-division. Then you just need a simple formula to extract each graphic based on an index. More complex methods exists (often called a texture atlas) but its overkill for many games.

Share this post


Link to post
Share on other sites

This topic is 3842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this