Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Making a animation function,

This thread is locked; no one can reply to it. rss feed Print
Making a animation function,
Mozzie
Member #12,685
March 2011

Hey guys,
I have took it upon myself to coming up with ideas for creating a function for animating a sprite. The parametres will/should look like this.

sprite_animate(Bitmap, FrameDimensionH, FrameDimensionW, StartFrame, EndFrame)

Okay, now here I will explain how it works. Please note, that this function will probably only work for a non varying frame sized animation. so here we go, you will declare a bitmap and assign a sprite strip/bmp to it. You will then set the frame dimensions like 32x32 or 16x16. It will then find those frames and order them from 0 to "the last frames". So thats how it will work, but I still have to get my head around the coding. Hence why I am asking you guys for help on this, and what I should do?

William Labbett
Member #4,486
March 2004
avatar

Not that I'm an expert but here's two cents :-

I think you need to think of it in stages instead of one function that does everything.

something like this :

update_animtion_frame()

draw_animation_frame(int frame_number, etc...)

Now the way I do the update of the frame is tied into the timing loop.

Here's my code : as basic as I can make it - that's how I code but it's C.

while( old_time < al_get_timer_count(timer))
        {
            ++old_time;
            
    

      --hero_frame_counter;
      if(hero_frame_counter <= 0)
      {
        hero_frame_counter = HERO_TICKS_PER_FRAMEUPDATE;
        
        update_hero_frame();
      }

As you can see every time the loop runs the hero_frame_counter gets one knocked off it. That means for each tick of the timer. When it reaches 0 it's time to move to the next frame.

When this loop stops, then the draw function gets called and the right frame gets called/** edit : drawn **/. Hopefully this would be a subsequent frame - ie frame 4 after frame 3 but if the previous draw took a long time then the logic loop (above) will get called more times in order to catch up with the actual time.

As far as I know this the way to do it.

HERO_TICKS_PER_FRAMEUPDATE is 30 which means that the loop must be called 30 times for hero_frame_counter to get to 0. When it does, hero_frame_counter is set back to 30.

My timer does 240 ticks per second so assuming the draw function isn't slowing things down, the frame changes 8 times per second ie at 30 ticks, 60 ticks, 90 ticks etc....

It's a bit of headache to get but using a proper timing loop will mean your game will look the same on different processors which run at different speeds.

Please ask any questions you need to.

/** ED : but I'm now off to bed..

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Here's a working win32 exe and source code that shows a simple stick figure animation (because my pixel art is severely lacking). It has everything you need to use animations in your program except for functions to load bitmaps from a spritesheet (which can vary in form widely).

AnimationTest.zip

Look at Animation.hpp to see what functions are available to use and at AnimationTest.cpp to see a usage example. The heart of the animation is in the AnimationBase::SetFrameTime function :

#SelectExpand
1int AnimationBase::SetFrameTime(double frame_time) { 2 frametime = frame_time; 3 double short_frame_time = frametime; 4 double num_loops = 0.0; 5 switch (anim_type) { 6 case FORWARD_ONCE : 7 if ((frametime < 0.0) || (frametime >= duration)) { 8 frame_num = -1; 9 loop_num = -1; 10 } else { 11 frame_num = (int)(frametime*frames_per_sec); 12 loop_num = 0; 13 } 14 break; 15 case BACKWARD_ONCE : 16 if ((frametime < 0.0) || (frametime >= duration)) { 17 frame_num = -1; 18 loop_num = -1; 19 } else { 20 frame_num = (num_frames - 1) - (int)(frametime*frames_per_sec); 21 loop_num = 0; 22 } 23 break; 24 case FORWARD_AND_BACK_ONCE : 25 if ((frametime < 0.0) || (frametime >= 2.0*duration)) { 26 frame_num = -1; 27 loop_num = -1; 28 } else { 29 if (frametime < duration) { 30 frame_num = (int)(frametime*frames_per_sec); 31 } else { 32 frame_num = (num_frames - 1) - (int)((frametime-duration)*frames_per_sec); 33 } 34 loop_num = 0; 35 } 36 break; 37 case FORWARD_REPEAT : 38 loop_num = 0; 39 if (frametime < 0.0) { 40 frame_num = -1; 41 loop_num = -1; 42 } else { 43 if (frametime >= duration) { 44 num_loops = frametime/duration; 45 loop_num = (int)num_loops; 46 short_frame_time = frametime - duration*(double)(loop_num); 47 } 48 frame_num = (int)(short_frame_time*frames_per_sec); 49 } 50 break; 51 case BACKWARD_REPEAT : 52 loop_num = 0; 53 if (frametime < 0.0) { 54 frame_num = -1; 55 loop_num = -1; 56 } else { 57 if (frametime >= duration) { 58 num_loops = frametime/duration; 59 loop_num = (int)num_loops; 60 short_frame_time = frametime - duration*(double)(loop_num); 61 } 62 frame_num = (num_frames - 1) - (int)(short_frame_time*frames_per_sec); 63// frame_num = (int)(short_frame_time*frames_per_sec); 64 } 65 break; 66 case FORWARD_AND_BACK_REPEAT : 67 loop_num = 0; 68 if (frametime < 0.0) { 69 frame_num = -1; 70 loop_num = -1; 71 } else { 72 if (frametime >= 2.0*duration) { 73 num_loops = frametime/(2.0*duration); 74 loop_num = (int)num_loops; 75 short_frame_time = frametime - (2.0*duration)*(double)loop_num; 76 } 77 if (short_frame_time < duration) { 78 frame_num = (int)(short_frame_time*frames_per_sec); 79 } else { 80 frame_num = (num_frames - 1) - (int)((short_frame_time-duration)*frames_per_sec); 81 } 82 } 83 break; 84 } 85 if (loop_stop_num != -1) { 86 if (loop_num > loop_stop_num) { 87 frame_num = -1; 88 loop_num = -1; 89 } 90 } 91 return loop_num; 92}

Note that this is ripped out of my library, so not everything applies - the AnimationBase SetColor, SetRotation, and SetScale functions will not work with the SimpleAnimation class because it doesn't allocate those.

Mozzie
Member #12,685
March 2011

Interesting, thanks. Erhm, does allegro have an irc, so we can live chat about it?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Go to: