Making a animation function,
Mozzie

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

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

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

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

Edgar Reynaldo

There's #allegro on irc.freenode.net, but I'll probably only be up another hour today. Ask all the questions you want here and I'll answer them today if you're quick or else tomorrow.

Thread #606852. Printed from Allegro.cc