Sign in to follow this  
Nate Hale

Sprite Animation Structure

Recommended Posts

I'm building my own 2D platformer in C++/SDL, but I want to keep it simple and extendable. As such, I'm thinking hard about how to rewrite my sprite classes, specifically the parts that have to do with animation. Simply put, each sprite object should contain some kind of list of rectangle structures (x, y, width, height, all integers) which will specify where on the main sprite sheet, the graphics engine should look to get that sprite's current frame. Since each type of sprite may contain any number of animations and each animation may contain a variable number of frames, the previous classes I've written used a nested vector system for animation. The sprite class contained a vector of animation objects. Each animation object contained a vector of rectangles (frames of animation). So here's an example. sprite object(contains vector of animations as one of its members) animation vector(contains 3 animations so far) animation vector.at(0) == run animation vector.at(1) == jump animation vector.at(2) == shoot run consists of 12 frames of animation jump consists of 8 frames of animation shoot consists of 4 frames of animation My question now is, can anyone think of a better way to organize this? I would prefer to be more conservative with my animation system. Ideas? Advice?

Share this post


Link to post
Share on other sites
Quote:
My question now is, can anyone think of a better way to organize this? I would prefer to be more conservative with my animation system. Ideas? Advice?
Can you clarify what you mean by 'conservative'?

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
My question now is, can anyone think of a better way to organize this? I would prefer to be more conservative with my animation system. Ideas? Advice?
Can you clarify what you mean by 'conservative'?


well that system lends itself to long, nested access commands. Here's an example.

If I wanted to access a coordinate of a frame, I would have to write something like

spriteObject.animationVector.at(3)->frameVector.at(2).xCoordinate = 135




And that can get disorganized very quickly. I know it's simple to write functions to do this in a much easier way like
spriteObject.access(animation 3, frame 2)
, but nested structures can get messy fast and you can easy lose track of the sizes of the inner structures.

Can you think of a simpler, better organized way to do this?

Share this post


Link to post
Share on other sites
Ah, I see. Well, without getting too complicated about it, the first thing I'd probably do is make a separate class to represent the 'animation frame' concept. This class would store a reference to a sprite sheet, and a rectangle indicating from what part of the sprite sheet to render. (Note that at this point you could probably give the class a more generic name than 'animation frame', since there's nothing about it that specifies that it should be part of an animation.)

You could certainly take a more abstract approach than this, but a simple way to make use of this class would be either to have it do the rendering itself, or to pass it to a rendering module that queries it for the relevant info (e.g. texture and frame rect), and then renders accordingly.

The 'animation' class would then contain a collection of these 'frame' objects, along with info about animation speed, whether the animation loops or oscillates, etc. It would also keep track of the currently active frame, and would be responsible for switching from frame to frame based on the time delta for the current update. The animation object would also be responsible for rendering itself.

Finally, you have a class that contains a collection of 'animation' objects, along with information such as which animation is currently active and how to switch from one animation to another. This class can also update and render itself (with most of the actual work being done by the 'animation' and 'frame' classes).

To be honest, I've never actually had occasion to write an animation system of this sort from scratch, and I'm sure there are better ways to structure it than what I've described. However, the main point I'm trying to make here is that, with proper design, you should be able to 'nest' the objects in the system in a logical way (as you're doing currently) while avoiding awkward syntax like in the examples you posted.

The key here is that you shouldn't be 'drilling down' manually through the hierarchy in order to manipulate things like rectangle coordinates (which really should be private data managed by the class that directly contains them). With the approach I described above, your code would end up looking more like this:
sprite->switch_to_animation("walk");
sprite->update_animation(time_delta);
sprite->render(renderer);

// In the sprite 'render' function:
my_animations[current_animation]->render(renderer);

// In the animation 'render' function:
my_frames[current_frame]->render(renderer);

// In the frame 'render' function:
renderer->render_rect(my_texture, my_rect);

Share this post


Link to post
Share on other sites
Hmm. You have some very good points. I sincerely thank you for sharing your thoughts on this.

My experience writing the first iteration of this animation system was so disorganized, I failed to see that the core tree structure of Sprite->Animation->Frame->Cooridnates does make sense. I have to be careful this time however.

A main focus for me, in this engine at least, is to keep ALL the graphics related code in the graphics classes. In order for a sprite to render itself, it would require access to the graphics API (SDL), but to keep things simple, organized and independent, I'm not going to do that.

However, your idea for each sprite to update itself is something that I hadn't considered. That seems to make a lot of sense from this design standpoint. Thanks!

Share this post


Link to post
Share on other sites

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