SDL 1.2 Have to press twice key for events to take effects

212 views Asked by At

I got a loop into my main in order to catch events. If the player type "1" then I call the function play(), which contain a loop for events too (for moves etc...). I really don't understand why, but I have to press twice ESCAPE in order to leave the game, and others key just don't seems recognized. If I delete my loops into my main, then all goes OK.

Here's my loop in the main :

while(continuer)
    {
        SDL_WaitEvent(&event);

        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
                break;

            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                        continuer = 0;
                        break;

                    case SDLK_KP1:
                        play(screen);
                        break;
                }
                break;
        }
    } 

And here's my function (she's still in progress, so don't be shocked if it seems A LOOOOT stupid :D)

void play(SDL_Surface* screen)
{
    int i=0, j=0, continuer=1;
    int elements[LARGEUR_MAP][HAUTEUR_MAP];
    char object =' ';
    FILE* level = NULL;
    SDL_Surface *lvl[LARGEUR_MAP][HAUTEUR_MAP],*mario[4];
    SDL_Rect posElem, posMario;
    SDL_Event event;

screen = SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE,32,SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,255,255,255));

mario[HAUT] = IMG_Load("images\\mario_haut.gif");
mario[DROITE] = IMG_Load("images\\mario_droite.gif");
mario[BAS] = IMG_Load("images\\mario_bas.gif");
mario[GAUCHE] = IMG_Load("images\\mario_gauche.gif");

//Ouverture du fichier contenant les infos du niveau
level = fopen("lvl.txt","r");

if(level == NULL)
{
    fprintf(stderr,"Erreur lors de l'ouverture du fichier");
    exit(EXIT_FAILURE);
}

//Boucle pour lire le fichier et placer les éléments du décor
for(j=0;j<HAUTEUR_MAP;j++)
{
    for(i=0;i<LARGEUR_MAP;i++)
    {
        object = fgetc(level);
        if(object == '\n')
            object = fgetc(level);
        switch(object)
        {
            case 'm':
                lvl[i][j] = IMG_Load("images\\mur.jpg");
                elements[i][j] = MUR;
                posElem.x = i*TAILLE_BLOC;
                posElem.y = j*TAILLE_BLOC;
                SDL_BlitSurface(lvl[i][j], NULL, screen, &posElem);
                break;

            case 'o':
                lvl[i][j] = IMG_Load("images\\objectif.png");
                elements[i][j] = OBJECTIF;
                posElem.x = i*TAILLE_BLOC;
                posElem.y = j*TAILLE_BLOC;
                SDL_BlitSurface(lvl[i][j], NULL, screen, &posElem);
                break;

            case 'c':
                lvl[i][j] = IMG_Load("images\\caisse.jpg");
                elements[i][j] = CAISSE;
                posElem.x = i*TAILLE_BLOC;
                posElem.y = j*TAILLE_BLOC;
                SDL_BlitSurface(lvl[i][j], NULL, screen, &posElem);
                break;

            case 'M':
                lvl[i][j] = IMG_Load("images\\mario_bas.gif");
                elements[i][j] = MARIO;
                posElem.x = i*TAILLE_BLOC;
                posElem.y = j*TAILLE_BLOC;
                SDL_BlitSurface(lvl[i][j], NULL, screen, &posElem);
                break;

            default :
                elements[i][j] = VIDE;
                break;
        }
    }
}

SDL_Flip(screen);
fclose(level);

//Code à l'arrache... Je met en dur la position de Mario, on verra plus tard pour l'automatisation ~~
i = 5;
j = 2;
posMario.x = i * TAILLE_BLOC;
posMario.y = j * TAILLE_BLOC;

while(continuer)
{
    SDL_WaitEvent(&event);

    switch(event.type)
    {
        case SDL_QUIT:
            continuer = 0;
            break;

        case SDL_KEYDOWN:
            switch(event.key.keysym.sym)
            {
                case SDLK_UP:
                    continuer = 0;
                    if(elements[i-1][j] != MUR && elements[i-1][j] != CAISSE_OK && i != 0)
                    {
                        posMario.x = (i-1)*TAILLE_BLOC;
                        posMario.y = j*TAILLE_BLOC;

                        if(elements[i-1][j] == CAISSE && elements[i-2][j] != MUR && elements[i-2][j] != CAISSE && elements[i-2][j] != CAISSE_OK && (i-2)>0)
                        {
                            SDL_FillRect(lvl[i][j], NULL, SDL_MapRGB(screen->format,255,255,255));
                            SDL_BlitSurface(mario[HAUT],NULL,screen,&posMario);
                            SDL_Flip(screen);
                        }
                    }
                    break;

                case SDLK_ESCAPE:
                    continuer = 0;
                    break;
            }
    }
}
}
1

There are 1 answers

1
MaKo On BEST ANSWER

As far as I understood, you have two (nested) event loops, both using their local 'continuer' variable. When you have entered the inner loop, pressing escape comes out from that one to the outer one: you need to press esc again to come out from that loop.

Depending on what you want, one possible quick solution could be e.g. returning true or false from play() to indicate, if player wants to exit the game. Personally I think that making nested event loops behaving nicely can be troublesome (when they are big and deep), but sadly in many cases you can't avoid them. Be careful with them, if you can.