Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Slowing down animation

This thread is locked; no one can reply to it. rss feed Print
Slowing down animation
dothedru22
Member #7,325
June 2006

I've searched and searched this forum, gamedev and other language forums(blitz, dark basic, etc) without a really specific answer. How would I go about slowing animation of a character. Like I got the the fps limiting to 30 fps but the frames of the actual character are still to fast. I don't care what language you write it in(although C would be best). I just need some logic or the actual code. thanks for any help.

right now i have something like this.

1void drawScreen(BITMAP* b, struct S_Player* p) {
2
3 while (game_time > 0) {
4
5 game_time --;
6 updateInput(p); //Input
7 }
8
9 clear_bitmap(b);
10
11 if (p->key == 0) {
12
13 draw_sprite_h_flip(b,p->img[p->current],p->x,p->y);
14
15 } else draw_sprite(b,p->img[p->current],p->x,p->y);
16
17 hline(b,0,190,320,makecol(255,255,255));
18 blit(b,screen,0,0,0,0,SCREEN_W,SCREEN_H);
19}
20 
21 
22void updateInput(struct S_Player*p) {
23
24 if (key[KEY_RIGHT]) {
25 p->key = 1;
26 p->current++;
27 if (p->current > 5) p->current = 1;
28 p->x += p->playerspeed + 4;
29
30 } else if (key[KEY_LEFT]) {
31
32 p->key = 0;
33 p->current++;
34 if (p->current > 5) p->current = 1;
35 p->x += -p->playerspeed - 4;
36
37 } else if (key[KEY_UP]) {
38
39 p->current = 7;
40
41 } else if (key[KEY_DOWN]) {
42
43 p->current = 8;
44
45 } else p->current = 0;
46}

the code is called in a while loop in main.c

23yrold3yrold
Member #1,134
March 2001
avatar

Keyframes, my friend. Keyframes. :) Fither that, or you want to increment p->current every 5 logic loops or something.

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

Jonny Cook
Member #4,055
November 2003

You should be using some kind of animation structure. Each frame should have it's own delay. Maybe something like this.

1 
2stuct Animation {
3 int num;
4 int delay;
5 int tick;
6 int frame;
7}
8 
9Animation *createAnimation(int num, int delay) {
10 Animation *a = malloc(sizeof(Animation));
11 a->num = num;
12 a->delay = delay;
13 a->tick = 0;
14 return a;
15}
16 
17void updateAnimation(Animation *a) {
18 ++ tick;
19 if (tick >= delay) {
20 tick = 0;
21 ++ frame;
22 if (frame >= num) {
23 frame = 0;
24 }
25 }
26}

Something like that. If you want more control over your animation, you can have an array of delays (a separate delay for each individual frame).

The face of a child can say it all, especially the mouth part of the face.

dothedru22
Member #7,325
June 2006

hey thanks for the replies so fast. i like the idea you had Johnny. I had tried something sortof of the same concept earlier without much luck. It definatly works its just that the frames are really choppy. I feel that when im doing that all im doing is creating a rest function. Its almost the same thing. But I appreciate the help so fast.

23yrold3yrold
Member #1,134
March 2001
avatar

Quote:

Each frame should have it's own delay.

Yeah, that's what I meant by 'keyframe'; I should have elaborated. :)

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

Jonny Cook
Member #4,055
November 2003

Quote:

I feel that when im doing that all im doing is creating a rest function. Its almost the same thing.

Almost, but not quite. With rest, the program exectution stops until rest returns. This would cause your game to appear to be laggy, which you certainly do not want. I've used this method many times before (I believe it's quite standard), so it should work for you.

The face of a child can say it all, especially the mouth part of the face.

dothedru22
Member #7,325
June 2006

hmm well maybe its my implementation of it or something. i changed mine to the way you did yours. heres what i have

1void drawScreen(BITMAP* b, struct S_Player* p) {
2
3
4 while (game_time > 0) {
5
6 game_time --;
7 updateInput(p); //Input
8 }
9 clear_bitmap(b);
10
11 if (p->key == 0) {
12
13 draw_sprite_h_flip(b,p->img[p->current],p->x,p->y);
14
15 } else draw_sprite(b,p->img[p->current],p->x,p->y);
16
17
18 hline(b,0,190,320,makecol(255,255,255));
19
20 blit(b,screen,0,0,0,0,SCREEN_W,SCREEN_H);
21}
22 
23void updateInput(struct S_Player*p) {
24
25 if (key[KEY_RIGHT]) {
26
27 p->tick ++;
28 if (p->tick >= 4) {
29
30 p->key = 1;
31 p->tick = 0;
32 p->current++;
33
34 if (p->current > 5) p->current = 1;
35
36 p->x += p->playerspeed + 2;
37 }
38
39 } else if (key[KEY_LEFT]) {
40
41 p->tick ++;
42
43 if (p->tick >= 4) {
44 p->key = 0;
45 p->tick = 0;
46 p->current++;
47
48 if (p->current > 5) p->current = 1;
49
50 p->x += -p->playerspeed - 2;
51 }
52
53 } else if (key[KEY_UP]) {
54
55 p->current = 7;
56
57 } else if (key[KEY_DOWN]) {
58
59 p->current = 8;
60
61 } else p->current = 0;
62}

1#include "player.h"
2 
3 
4struct S_Player createPlayer(void) {
5
6 struct S_Player* player = malloc(sizeof(struct S_Player));
7
8 player->dat = load_datafile("image/sprite.dat");
9
10 player->img[0] = (BITMAP *)player->dat[stand].dat;
11 player->img[1] = (BITMAP *)player->dat[run1].dat;
12 player->img[2] = (BITMAP *)player->dat[run2].dat;
13 player->img[3] = (BITMAP *)player->dat[run3].dat;
14 player->img[4] = (BITMAP *)player->dat[run4].dat;
15 player->img[5] = (BITMAP *)player->dat[run5].dat;
16 player->img[6] = (BITMAP *)player->dat[run6].dat;
17 player->img[7] = (BITMAP *)player->dat[lookup].dat;
18 player->img[8] = (BITMAP *)player->dat[crouch].dat;
19 player->x = 10;
20 player->y = 150;
21 player->playerspeed = 6;
22 player->current = 1;
23 player->key = 1;
24 player->tick = 0;
25
26 return *player;
27}
28 
29void deletePlayer(struct S_Player* p) {
30
31 unload_datafile(p->dat);
32 free(p);
33
34}

Kitty Cat
Member #2,815
October 2002
avatar

Your createPlayer function is creating a memory leak, and your deletePlayer function is bugged. When you allocate something, you need to keep a pointer to it around so you can free it later. When you return *player, you're basically just copying out the data and getting rid of the pointer. And when calling deletePlayer, I assume you're using like you did before (ie. deletePlayer(&something_on_the_stack);), meaning it's trying to free memory it can't.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

dothedru22
Member #7,325
June 2006

so like i need a pointer to a function?

Steve Terry
Member #1,989
March 2002
avatar

Either update using floats (i.e. a number less than 1) or use a timer and keep a delay variable with each object.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

so like i need a pointer to a function?

No. You need a pointer to an object.

struct S_Player *player = createPlayer();
...
destroyPlayer(player);
player = NULL;

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

dothedru22
Member #7,325
June 2006

Quote:

Either update using floats (i.e. a number less than 1)

thats a good idea. thanks. it works but i have obviously type cast the array index to a integer every looop. not sure if this will cause major slow down in the long run. or if using a float in generals gonna cause much problem.

Quote:

No. You need a pointer to an object.

struct S_Player *player = createPlayer();
...
destroyPlayer(player);
player = NULL;

not sure what your saying. isnt that what i already have.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

not sure what your saying. isnt that what i already have.

No, because createPlayer doesn't return a pointer. I can't say for 100% certainty what you're doing though because you haven't showed the code since you updated the code. But if you have:

struct S_Player player = createPlayer();
...
destroyPlayer(&player);

Then you have a memory leak, still have the player object on the stack, and try to free stack memory (all very bad).

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

dothedru22
Member #7,325
June 2006

oh i see. thanks man.
well everytime i try what you had
struct S_Player* player = createPlayer();

i get a message saying i cant do that. says something like imcompatable types.

Kitty Cat
Member #2,815
October 2002
avatar

Because createPlayer isn't returning a pointer. You need to make it return struct S_Player* instead of struct S_Player.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

dothedru22
Member #7,325
June 2006

i thought that was sortof what i was doig when i said return *player. im sorry just not getting it. i've tried a bunch of ways.

Kitty Cat
Member #2,815
October 2002
avatar

return *player; means you're deferencing the player pointer, and copying it to the object you're setting in main(). return player; will copy the pointer value (which is what you want), but you have to define the function to return a pointer, and set a pointer in main(). eg:

struct S_Player *createPlayer(void) {
    struct S_Player *player = malloc(sizeof(struct S_Player));
    ...
    return player;
}

int main()
{
    ...
    struct S_Player *player = createPlayer();
    ...
    destroyPlayer(player);
    player = NULL;
    ...
}

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

dothedru22
Member #7,325
June 2006

oh i see man. not sure the theory behind it. but it works now. hopefully this weekend i'll read up on this more. i thought i knew the language pretty well but i guess not. i appreicate your help so fast.

Neil Walker
Member #210
April 2000
avatar

If you need any further information/examples on coding your animations, download and check out the code for the animation part of my library mentioned in my sig. all the code is handled in the method, 'nextframe'.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Matt Kindy
Member #7,331
June 2006
avatar

If all else fails, you could play the same frame twice, effectively cutting the FPS in half shrugs

Jonny Cook
Member #4,055
November 2003

That's exactly what a frame delay accomplishes.

The face of a child can say it all, especially the mouth part of the face.

Go to: