Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » timers and animation

This thread is locked; no one can reply to it. rss feed Print
timers and animation
Marco Radaelli
Member #3,028
December 2002
avatar

I have a couple of sprites with simple animation: just 3 different frames.

Just to test if it works, I written a test program in which, inside a loop I do

vsync();
rest(80);
draw_sprite(...);

Everything goes right, the animations change with regularity and the effect is enough for me.

Naturally, in the final game there will not be any vsync() and rest().
I'm wondering if installing a timer with MSECS_TO_TIMER(80) will be precise enough or if there's another way to do that.

Basically the timer will increase the index in the sprite's array.

Richard Phipps
Member #1,632
November 2001
avatar

Courtesy of Chris Barry, a generic timing framework for games:

1volatile int game_time = 0;
2 
3 .....
4 
5// Timer function
6 
7void Timer(void)
8{
9 game_time++;
10}END_OF_FUNCTION(Timer);
11 
12 .....
13 
14int main()
15{
16 // standard initialization
17 
18 allegro_init();
19 install_keyboard();
20 set_color_depth(16);
21 set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
22 
23 // usual timer setup
24 
25 LOCK_VARIABLE(game_time);
26 LOCK_FUNCTION((void*)Timer);
27 install_int_ex(Timer, BPS_TO_TIMER(120));
28
29 // the game loop
30 
31 do{
32 while(game_time > 0)
33 {
34 // all game logic goes here
35 
36 
37 // necessary for keeping time
38 
39 game_time--;
40 }
41
42 // all drawing code goes here
43 
44 
45 }while(!key[KEY_ESC]); // end of game loop
46 
47 
48 return 0;
49}END_OF_MAIN()

So you should only increase the sprite array num in the logic section of the code. Not in the timer routine, that should only increase the timer variable..

There have been many threads on timing, do a search on these forums if this code doesn't help you.

:)

Marco Radaelli
Member #3,028
December 2002
avatar

mmh... actually I was wondering if a timer in MSECS_TO_TIMER(80) does the same job (but better) as rest(80)...

Richard Phipps
Member #1,632
November 2001
avatar

Jonatan Hedborg
Member #4,886
July 2004
avatar

where as rest only pauses the program for n milliseconds, a timer calls a certain function n times per second, (in this case) increasing a variable that can then be used universially through your program for time-based operations.

rest wont actually make programs run the same speed at all computers either. The only(?) use for rest is to give back unused CPU cycles to the OS.

Tobias Dammers
Member #2,604
August 2002
avatar

rest() used to be useful in the pre-multi-tasking era, when a single process occupied the whole machine. In those golden DOS days, rest() was sometimes used for actual resting.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Marco Radaelli
Member #3,028
December 2002
avatar

I said:

Naturally, in the final game there will not be any vsync() and rest().
I'm wondering if installing a timer with MSECS_TO_TIMER(80) will be precise enough or if there's another way to do that.

Sometimes I feel you just red something else... sorry for that.

I suppose all your posts mean "Yes, that timer will do what rest() did in your test code".

Thanks 8-)

Jonatan Hedborg
Member #4,886
July 2004
avatar

Uhm, no. Rest does not do the same thing as a timer would. Rest pauses the program, then executes the "frame" as normal. timer would (in some manner, depending on design) limit/control how often the frame is updated. Timer would give the same result (or near enough) on all computers, while rest would not (as it still takes diferent amount of time to execute the rest of the code depending on the computer it's run on etc)

Marco Radaelli
Member #3,028
December 2002
avatar

::)

Let me re-explain it, only this time.

I have a sprite with 3 animation frames. While testing other things I had to understand how many milliseconds should pass between one frame and another.

To speed up the testing I didn't go with setting timers and decide how to handle that specific animation, because halting the loop with rest(), a loop which just draws the sprite's frames, will be enough to understand if I should change frame every 80 milliseconds or 50 milliseconds or x milliseconds.

Now that the test has been done, I'll have to design the whole program.

It will naturally use a timer to handle overall speed, like Richard suggested and in the way it is described in the Allegro FAQ, so I'm not going to use rest() to wait to change the frame.

Beside that timer I'm thinking about a specific timer which will tick every 80 milliseconds (that's why I asked if a timer with MSECS_TO_TIMER(80) will be precise enough) to change the actual frame.

There are two different sprites and each has a three-frame animation, so that timer should be good. I think I should not change the animation frame during the logic cycle, because it may result in too fast animation or too slow logic updating, but then I'll see the results in the playtesting stage.

Again, thank you all for the help :)

23yrold3yrold
Member #1,134
March 2001
avatar

So you're all set? Question dealt with?

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Marco Radaelli
Member #3,028
December 2002
avatar

No more, right now :)

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

Beside that timer I'm thinking about a specific timer which will tick every 80 milliseconds (that's why I asked if a timer with MSECS_TO_TIMER(80) will be precise enough) to change the actual frame.

You don't really need that. The best idea IMHO is to make the game logic independent from timer rate. Make a timer function that executes every n milliseconds, and increments a counter by n. This way, the counter will contain the number of milliseconds since the last check. Use this timer to update your logic*. You can always change n, with no real side-effect on the logic, except that with lower timer rates gameplay will become laggy and less fluid, while higher timer rates may increase system load. For the graphics update, I think the best plan is to lock in with the vertical retrace. This gives the smoothest results. How you do that depends on platform and buffer method.

  • Two options: Either make a variable-delta logic update, or do:

(while counter >= logic_delay) {
 update_logic();
 counter -= logic_delay;
}

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Go to: