Animation with sdl and C

Started by
3 comments, last by flashingchicken 17 years, 10 months ago
hello, I'm trying to animate a sprite on the screen and move it with the arrow keys. While I press the right key, for example, the sprite must move right while start the animation. i have tried with a function thread that implements the animation. Here the code int thread_func(void *unused) { while(1) { int i; for (i = 1; i < 7; i++) { frameIndex = i; SDL_FillRect(g_pMainSurface,&g_Rect,g_Color); SDL_BlitSurface(g_pBitmapSurfac[frameIndex],&g_SrcRect, g_pMainSurface, &g_DstRect); SDL_UpdateRect(g_pMainSurface,0,0,0,0); SDL_Delay(100); } } return(0); } This function redraw for ever all frame (7 frame) of sprite animation (a walking bouy). The problem is that i want the thread_func function start only when the right key is pressed. Therefore i need something in order to suspend the thread when the key is not pressed and restart it when is pressed. Here the mai code: int main(int argc, char* argv[]) { Uint32 setScreenChoise = SDL_ANYFORMAT | SDL_DOUBLEBUF; if (argc > 1) { int argom = *argv[1]; if (argom == 'f') { setScreenChoise = SDL_FULLSCREEN; } else return(0); } g_pMainSurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,32,setScreenChoise); if (SDL_Init(SDL_INIT_VIDEO)==-1) { fprintf(stderr,"Error initialization SDL\n"); exit(1); } else { fprintf(stdout,"SDL init\n"); atexit(SDL_Quit); } init(); g_Color=SDL_MapRGB(g_pMainSurface->format,g_Red,g_Green,g_Blue); g_Rect.x = 0; g_Rect.y = 0; g_Rect.w = 640; g_Rect.h = 480; SDL_FillRect(g_pMainSurface,&g_Rect,g_Color); SDL_UpdateRect(g_pMainSurface,0,0,0,0); g_SrcRect.w=g_DstRect.w=g_pBitmapSurface[0]->w; g_SrcRect.h=g_DstRect.h=g_pBitmapSurface[0]->h; g_SrcRect.x=g_SrcRect.y=0; g_DstRect.x=256; g_DstRect.y=176; SDL_BlitSurface(g_pBitmapSurface[0], &g_SrcRect, g_pMainSurface, &g_DstRect); SDL_UpdateRect(g_pMainSurface,0,0,0,0); thread = SDL_CreateThread(thread_func, NULL); if(!g_pMainSurface) { fprintf(stderr,"Unable to create main surface\n"); exit(1); } tank's and sorry for my english :)
Advertisement
You shouldn't call SDL drawing functions in threads other than your main thread : Source.
Ok, tank's.
But how can i create an animation in C of a walking sprite?

I have implemented the movement of a static sprite around the screen with a pression of one directional key, but i want also an animation of the sprite when i move it.

If you have an exemple.
One prevoius solution that i have tried was here:

if (movFlag)
{
if (directionFlag == RIGHT_FLAG)
{
if (g_DstRect.x < RIGHT_LIMIT)
{
g_DstRect.x += 4;
}

if (frameIndex <= 6 && frameIndex > 0)
{
frameIndex++;
SDL_Delay(80);

}
else frameIndex = 1;

}
else if (directionFlag == LEFT_FLAG)
{
if (g_DstRect.x > LEFT_LIMIT)
g_DstRect.x -= 4;

if (frameIndex <= 13 && frameIndex > 7)
{
frameIndex++;
SDL_Delay(80);

}
else frameIndex = 8;

}
else if (directionFlag == DOWN_FLAG)
{

if (g_DstRect.y < DOWN_LIMIT)
g_DstRect.y += 5;
if (frameIndex <= 20 && frameIndex > 14)
{
frameIndex++;
SDL_Delay(100);

}
else frameIndex = 15;

}
else if (directionFlag == UP_FLAG)
{
if (g_DstRect.y > UP_LIMIT)
g_DstRect.y -= 5;
if (frameIndex <= 27 && frameIndex > 21)
{
frameIndex++;
SDL_Delay(100);

}
else frameIndex = 22;

}

}
SDL_FillRect(g_pMainSurface,&g_Rect,g_Color);
SDL_BlitSurface(g_pBitmapSurface[frameIndex], &g_SrcRect, g_pMainSurface, &g_DstRect);
SDL_UpdateRect(g_pMainSurface,0,0,0,0);

where for right, the animation frames are in g_pBitmapSurface[1 - 6], for left in g_pBitmapSurface[8 - 13] ecc.

The problem is that when i move the sprite, the movement isn't regular because the program must wait the animation and after can move.
If you can give me some kind of help...

...tank's
Try to use code tags

if (movFlag){if (directionFlag == RIGHT_FLAG){if (g_DstRect.x < RIGHT_LIMIT){g_DstRect.x += 4;}if (frameIndex <= 6 && frameIndex > 0){frameIndex++;SDL_Delay(80);}else frameIndex = 1;}else if (directionFlag == LEFT_FLAG){if (g_DstRect.x > LEFT_LIMIT)g_DstRect.x -= 4;if (frameIndex <= 13 && frameIndex > 7){frameIndex++;SDL_Delay(80);}else frameIndex = 8;}else if (directionFlag == DOWN_FLAG){if (g_DstRect.y < DOWN_LIMIT)g_DstRect.y += 5;if (frameIndex <= 20 && frameIndex > 14){frameIndex++;SDL_Delay(100);}else frameIndex = 15;}else if (directionFlag == UP_FLAG){if (g_DstRect.y > UP_LIMIT)g_DstRect.y -= 5;if (frameIndex <= 27 && frameIndex > 21){frameIndex++;SDL_Delay(100);}else frameIndex = 22;}}SDL_FillRect(g_pMainSurface,&g_Rect,g_Color);SDL_BlitSurface(g_pBitmapSurface[frameIndex], &g_SrcRect, g_pMainSurface, &g_DstRect);SDL_UpdateRect(g_pMainSurface,0,0,0,0);


It looks nicer and it is more easy to read :)
------------Something useful could be written here...
if i am understanding your problem correctly, the movement across the screen is not fluid, then you might want to add something to detect how long its been since the last frame was drawn, which might be solved like this

Uint32 old_time, new_time;
float delta_t;
new_time=SDL_GetTicks();

then, inside the game loop

old_time=new_time;
new_time=SDL_GetTicks();
delta_t=new_time-old_time;
Draw_Scene(delta_t, ...other stuff);

and in your Draw_Scene function multiply all movements by (delta_t/16.7), assuming ~60fps to be the ideal case.

This topic is closed to new replies.

Advertisement