user3212030
user3212030

Reputation: 1

SDL freeze (black screen)

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

Answers (1)

Bartlomiej Lewandowski
Bartlomiej Lewandowski

Reputation: 11180

There are two issues with your code.

  1. 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.

  2. 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

Related Questions