#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>
void DrawImage(SDL_Surface *img, SDL_Surface *dest, int x, int y)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.h = 50;
rect.w = 60;
SDL_BlitSurface (img, NULL, dest, &rect);
}
int main(int argc, char *argv[])
{
// Inizializzo SDL
if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
exit(1);
}
// pointers for all the directions
SDL_Surface *rx[8];
SDL_Surface *lx[8];
SDL_Surface *up[8];
SDL_Surface *dw[8];
SDL_Surface *frame;
rx[0] = IMG_Load("PG/right_0001.png");
rx[1] = IMG_Load("PG/right_0002.png");
rx[2] = IMG_Load("PG/right_0003.png");
rx[3] = IMG_Load("PG/right_0004.png");
rx[4] = IMG_Load("PG/right_0005.png");
rx[5] = IMG_Load("PG/right_0006.png");
rx[6] = IMG_Load("PG/right_0007.png");
rx[7] = IMG_Load("PG/right_0008.png");
lx[0] = IMG_Load("PG/left_0001.png");
lx[1] = IMG_Load("PG/left_0002.png");
lx[2] = IMG_Load("PG/left_0003.png");
lx[3] = IMG_Load("PG/left_0004.png");
lx[4] = IMG_Load("PG/left_0005.png");
lx[5] = IMG_Load("PG/left_0006.png");
lx[6] = IMG_Load("PG/left_0007.png");
lx[7] = IMG_Load("PG/left_0008.png");
up[0] = IMG_Load("PG/rear_0001.png");
up[1] = IMG_Load("PG/rear_0002.png");
up[2] = IMG_Load("PG/rear_0003.png");
up[3] = IMG_Load("PG/rear_0004.png");
up[4] = IMG_Load("PG/rear_0005.png");
up[5] = IMG_Load("PG/rear_0006.png");
up[6] = IMG_Load("PG/rear_0007.png");
up[7] = IMG_Load("PG/rear_0008.png");
dw[0] = IMG_Load("PG/front_0001.png");
dw[1] = IMG_Load("PG/front_0002.png");
dw[2] = IMG_Load("PG/front_0003.png");
dw[3] = IMG_Load("PG/front_0004.png");
dw[4] = IMG_Load("PG/front_0005.png");
dw[5] = IMG_Load("PG/front_0006.png");
dw[6] = IMG_Load("PG/front_0007.png");
dw[7] = IMG_Load("PG/front_0008.png");
atexit(SDL_Quit);
SDL_Surface *screen = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
if(screen == NULL){
fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
exit(1);
}
int isRunning = 1;
int animation = 0;
int i=0;
int s=0;
int e=6;
int X=0;
int Y=220;
int targetX=-500;
int targetY=0;
char current='X';
char dir='R';
// Creo un loop per tenere sempre la finestra attiva in visualizzazione
while(isRunning)
{
if (animation == 1)
{
if (current!='Y')
{
int appx = (X+67) - targetX;
if (appx != 0)
{
if (appx < 0)
{
dir='R';
X = X+1;
}
else
{
dir='L';
X = X-1;
}
}
else
{
current='Y';
}
}
else
{
int appy = (Y+270) - targetY;
if (appy != -270 && appy != 0)
{
if (appy < 0)
{
dir='B';
Y = Y+1;
}
else
{
dir='T';
Y = Y-1;
}
}
else
{
animation = 0;
current='X';
}
}
//temporize frames
if (s < e)
{
s = s +1;
}
else
{
s = 0;
//print frame
if (i > 5)
{
i = 0;
}
else
{
i = i + 1;
}
}
switch(dir)
{
case 'R':
frame = rx;
break;
case 'L':
frame = lx;
break;
case 'T':
frame = up;
break;
case 'B':
frame = dw;
break;
}
}
else
{
switch(dir)
{
case 'R':
frame = rx[0];
break;
case 'L':
frame = lx[0];
break;
case 'T':
frame = up[0];
break;
case 'B':
frame = dw[0];
break;
}
}
// Check if player quits
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button)
{
case SDL_BUTTON_LEFT:
targetX = event.button.x;
targetY = event.button.y;
animation = 1;
current='X';
break;
}
break;
case SDL_QUIT:
isRunning = 0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
isRunning = 0;
break;
case SDLK_RIGHT:
break;
case SDLK_LEFT:
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_RIGHT:
break;
case SDLK_LEFT:
break;
}
}
}
SDL_FillRect(screen, NULL, 0);
DrawImage(frame,screen,X,Y);
SDL_Flip(screen);
}
SDL_FreeSurface(rx[8]);
SDL_FreeSurface(lx[8]);
SDL_FreeSurface(up[8]);
SDL_FreeSurface(dw[8]);
}
[SDL] How to use ticks and have a constant frame rate
Hi everybody,
I'm trying to work on my humble little project and I need some info about how to use ticks for animations with SDL. I'm a newbie and I tried to realize a spite animation (a character that walks to north, south, east and west) in a very primitive (and useless) way, it works badly because I don't use ticks, I think. The problem is that it doesn't have a constant frame rate and it directly depends on cpu speed and memory occupation (you load something while running the animation, it slows down).
I'll show you my horrible code (remember I'm very newbie), I stored all the anim frames in 4 arrays (one for each direction, rx, lx, dw, up), is it correct? How to transform this animation using ticks so that it'll always have a constant frame rate? Ah, it is supposed to be a point and click interface so you have to point with your mouse and the character should reach the signed destination.
Thanks a lot guys. :)
I don't know the details of SDL, but in general, you have three choices:
- Base your motion and animation on the frame rate and lock the frame rate to a constant value. You would do it something like this:
This is the simplest method. I've never implemented a system like this, but from what I've heard, it is very difficult to get it to work well.int const LOCKED_FRAME_TIME = 50; // 50 ms is 20 fps int old_time = some_function_to_get_the_time() - LOCKED_FRAME_TIME; while ( game_is_running ) { int current_time = some_function_to_get_the_time(); int delta_time = old_time - current_time; if ( delta_time >= LOCKED_FRAME_TIME ); { Update(); Render(); old_time = current_time - ( delta_time - LOCKED_FRAME_TIME ); } else { Sleep( LOCKED_FRAME_TIME - delta_time ); } }
- Base your motion and animation off of real time and let the frame rate go as fast as possible. Something like this:
In most situations, this is the best choice.int old_time = some_function_to_get_the_time(); while ( game_is_running ) { int current_time = some_function_to_get_the_time(); int delta_time = old_time - current_time; Update( delta_time ); Render(); old_time = current_time; }
- Base your motion and animation off the real time, update in fixed time steps, and let the frame rate go as fast as possible. Something like this:
For a game that uses serious physics, this is probably the best choice because it will give the most accurate results. The drawback over the previous choice is that the Update function is called several times per frame, slowing down the frame rate.int UPDATE_TIME_STEP = 10; // 10 ms int old_time = some_function_to_get_the_time(); while ( game_is_running ) { int current_time = some_function_to_get_the_time(); int delta_time = old_time - current_time; while ( delta_time >= UPDATE_TIME_STEP ) { Update(); delta_time -= UPDATE_TIME_STEP; } Render(); old_time = current_time - delta_time; }
I have a tutorial on this.
*points to sig*
Its tutorial 10. I recommend you read tutorial 9 to understand how my timer class works since it's used in tutorial 10 to cap the frame rate.
*points to sig*
Its tutorial 10. I recommend you read tutorial 9 to understand how my timer class works since it's used in tutorial 10 to cap the frame rate.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement