Reputation: 1
Here is my full code.
When I click right for a few times(animation works normally), the screen freezes. I think the lines from if(SDL_GetTicks() - start_time < 1000)
on are the problem (because of too many executions?)?
const int SCREEN_WIDTH = 600;
const int SCREEN_HEIGHT = 500;
const int SCREEN_BPP = 32;
//The surfaces
SDL_Surface *background = NULL;
SDL_Surface *upMessage = NULL;
SDL_Surface *downMessage = NULL;
SDL_Surface *leftMessage = NULL;
SDL_Surface *rightMessage = NULL;
SDL_Surface *message = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *finish = NULL;
SDL_Surface *startStop = NULL;
SDL_Surface *one = NULL;
SDL_Surface *two = NULL;
SDL_Surface *three = NULL;
SDL_Surface *four = NULL;
SDL_Surface *five = NULL;
//The event structure
SDL_Event event;
SDL_Surface *load_image( std::string filename ){
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load( filename.c_str() );
//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized surface
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old surface
SDL_FreeSurface( loadedImage );
//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}
//Return the optimized surface
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Holds offsets
SDL_Rect offset;
//Get offsets
offset.x = x;
offset.y = y;
//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}
bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "Press an Arrow Key", NULL );
//If everything initialized fine
return true;
}
bool load_files()
{
//Load the background image
background = load_image( "background .png" );
message = load_image( "guy.png" );
finish = load_image( "finish .png" );
//If there was a problem in loading the background
if( background == NULL )
{
return false;
}
//If everything loaded fine
return true;
}
void clean_up()
{
//Free the surfaces
SDL_FreeSurface( background );
SDL_FreeSurface( upMessage );
SDL_FreeSurface( downMessage );
SDL_FreeSurface( leftMessage );
SDL_FreeSurface( rightMessage );
SDL_FreeSurface( startStop );
SDL_FreeSurface( one );
SDL_FreeSurface( two );
SDL_FreeSurface( three );
SDL_FreeSurface( four );
SDL_FreeSurface( five );
//Quit SDL
SDL_Quit();
}
void anim(SDL_Surface *number,std::string name[],int n){
number = NULL;
number = load_image(name[n] +".png" );
apply_surface( 0, 0, number, screen );
}
int main( int argc, char* args[] ){
bool quit = false;
bool start = true;
bool cilj_test = true;
int x=35,y=10;
bool animation = false;
Uint32 start_time = 0;
//The timer start/stop flag
bool running = false;
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Apply the background
apply_surface( 0, 0, background, screen );
//While the user hasn't quit
while( quit == false ){
//If there's an event to handle
if( SDL_PollEvent( &event ) ){
//If a key was pressed
if( event.type == SDL_KEYDOWN ){
//Set the proper message surface
switch( event.key.keysym.sym ){
case SDLK_UP:
break;
case SDLK_DOWN:
start=false;
if(y!=410 && animation==false){
y+=100;
SDL_FillRect( screen, 0, 0 );
background = NULL;
message = NULL;
background = load_image( "background .png" );
apply_surface( 0, 0, background, screen );
finish = load_image( "finish.png" );
apply_surface(506, 420, finish, screen );
message = load_image( "guy.png" );
apply_surface( x, y, message, screen );
// if()
}
break;
case SDLK_LEFT:
break;
case SDLK_RIGHT:
start=false;
if(x!=535 && animation==false){
x+=100;
SDL_FillRect( screen, 0, 0 );
background = NULL;
message = NULL;
background = load_image( "background.png" );
apply_surface( 0, 0, background, screen );
finish = load_image( "finish.png" );
apply_surface(506, 420, finish, screen );
message = load_image( "guy.png" );
apply_surface( x, y, message, screen );
if(x==535 && y==410){
start_time=SDL_GetTicks();
animation=true;
x=35,y=10;
}
}
break;
}
}
//If the user has Xed out the window
else if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
if(animation){
std::string name[5]={"one","two","three","four","five"};
if(SDL_GetTicks() - start_time < 1000){
anim(one,name,4);
} else if(SDL_GetTicks() - start_time > 1000 && SDL_GetTicks() - start_time < 2000){
anim(two,name,3);
} else if(SDL_GetTicks() - start_time > 2000 && SDL_GetTicks() - start_time < 3000){
anim(three,name,2);
} else if(SDL_GetTicks() - start_time > 3000 && SDL_GetTicks() - start_time < 4000){
anim(four,name,1);
} else if(SDL_GetTicks() - start_time > 4000 && SDL_GetTicks() - start_time < 5000){
anim(five,name,0);
} else if(SDL_GetTicks() - start_time > 5000){
SDL_FillRect( screen, 0, 0 );
background = NULL;
message = NULL;
background = load_image( "background.png" );
apply_surface( 0, 0, background, screen );
finish = load_image( "finish.png" );
apply_surface(506, 420, finish, screen );
message = load_image( "guy.png" );
apply_surface( x, y, message, screen );
animation=false;
start_time=0;
}
}
if( message != NULL ){
if(start){
apply_surface(35, 10, message, screen );
apply_surface(506, 420, finish, screen );
}
message = NULL;
}
//Update the screen
if( SDL_Flip( screen ) == -1 ){
return 1;
}
}
//Clean up
clean_up();
return 0;
}
Upvotes: 0
Views: 449
Reputation: 11180
There are two issues with your code.
You do not have a while loop, meaning that the application will draw once, get one input, and stop. You are experiencing a freeze because there are too many events on the event queue.
Not really the cause of your problem, but it would show up eventually. You are loading the image each time you want to draw it. Instead load all of the images before, and just apply the correct surface. If you won't loading the images and not freeing them will result in no running out of memory.
EDIT:
After seeing your whole code, it is the second issue that is the problem. Load all your images before the loop, and just blit them accordingly.
Upvotes: 2