Sign in to follow this  
Aardvajk

Time-based animation - pondering

Recommended Posts

I'm at work pondering how when I get home I can make my animations in my daft little game time-based rather than frame-based. Got the movement working time-based okay. Do you reckon it'll work if I have a local float it my animation class that has the elapsed time added to it each frame, then if it is greater than, say 1/25 (for 25 frames per second), WHILE it is greater than it subtract 1/25 from it and pump the animation loop, then leave whatever remains for the next frame and return the current animation index? If this is a dumb approach could someone let me know before 5pm so I don't waste the whole weekend? Ta

Share this post


Link to post
Share on other sites
Seems like a reasonable approach to me. I basically did the same thing. Your way accounts for tremendeous lag, too, which is good - sometimes you'll see people forget that they may need to incrememnt two or more animation frames for a given render frame. Have fun coding.

Share this post


Link to post
Share on other sites
That should work fine. One thing you could consider though is to make multiple subtractions until the float is less than 1/25. For example imagine that you just processed a heavy frame and now the counter is grater than 2/25 (due to the long process time of the last frame). If you only subtract 1/25 from this and pump the animation once you will still have a counter value greater than 1/25. If this continues over a number of heavy frames your animation will begin to lag behind.

To keep up in time you could make a loop of tests which pumps the animation loop until the counter is less than 1/25. Of course, if the counter is less than 1/25 to begin with the animation would not be pumped at all.

Good luck.

Share this post


Link to post
Share on other sites
I do something similar. If the actual time delta is more than, say, 1/20s, i make it delta = 1/20s. That way really ugly lags on the system won't surprise the player when objects teleport across the screen. I should point out that this is done on the raw time delta on the gameloop level, not in any specific class. I give each time-based class the time delta after i've played with it a bit. Also note that you can use this same technique to slow/stop time in general and consequently implement a usefull Pause() feature.

Share this post


Link to post
Share on other sites
I just recently designed a time-based animation system for sprites. Basically I had three classes: PlayCursor, Sequence, and Animation.

PlayCursor kept track of which sequence was playing, the current playing time, the time when the current frame will end (in miliseconds), the current frame being played, and the play status (playing, stopped, paused)

Sequence kept arrays of frame numbers and durations, so frames can be of varying lengths and the same frame image can be used multiple times in the sequence. It also controles play types (once, loop, ping pong)

Animation handled play commands (play, stop, pause), selecting sequences, loading, multiple play cursors to have the same sequence information be used for playing multiple sequences and independent starting and stopping (for instance, hundreds of enemies can all be doing different things while using the same sequence information).

Basically I send the current time in miliseconds to the Animation class. It adds the difference between the previous time and the current time to the play cursor's time. If the play cursor's time is greater than the frame's end time then the frame index number is increased, the new frame end time equals the current time plus the current frame's duration.

Example Diagram:
Texture Frame Layout:  1  2  3  4
5 6 7 8
9 10 11 12
13 14 15 16

A Sequence:
Frames Array = {2, 5, 3, 10, 12};
Duration Array = {100, 200, 50, 80, 1000};

A Play Cursor:
Sequence = 0;
Frame Index = 2; // which is frame_array[2] which equals frame 5
Current Time = 15000;
Frame Time = 15200; // when the frame will advance
Play status = ANIM_PLAY;


Usage Example:

Sprite s;
s.load("texture.png", texture_manager, gl_min_filter, gl_max_filter, mip_maping, x_frames, y_frames);

s.animation.create_sequences(sequence_count, cursor_count);
s.animation.make_sequence(sequence_num_1, start_frame, end_frame, duration_in_miliseconds, play_mode);
s.animation.make_sequence(sequence_num_2, frame_count, play_mode);
s.animation.set_sequence_frame(sequence_num_2, frame_0, frame_index_0, duration_0);
s.animation.set_sequence_frame(sequence_num_2, frame_1, frame_index_1, duration_1);
s.animation.set_sequence_frame(sequence_num_2, frame_2, frame_index_2, duration_2);
s.animation.set_sequence_frame(sequence_num_2, frame_3, frame_index_3, duration_3);

s.animation.select_sequence(play_cursor_1, sequence_num_1);
s.animation.select_sequence(play_cursor_2, sequence_num_2);
s.animation.action(play_cursor_1, ANIM_PLAY);
s.animation.action(play_cursor_2, ANIM_PLAY);

...

time = SDL_GetTicks();
s.update_anim(play_cursor_1, time);
s.draw(x, y);
s.update_anim(play_cursor_2, time);
s.draw(x2, y2);




I hope this will be helpful and give you some ideas.

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