Sign in to follow this  
negflar

Animation with sdl and C

Recommended Posts

negflar    122
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 :)

Share this post


Link to post
Share on other sites
negflar    122
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

Share this post


Link to post
Share on other sites
Vegettex    124
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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this