2014-12-24 67 views
0

爲了捕捉事件,我得到了一個循環。如果玩家輸入「1」,那麼我會調用函數play(),它還包含事件循環(用於移動等)。 我真的不明白爲什麼,但我必須按兩次ESCAPE才能離開遊戲,而其他人的鍵似乎並不認可。 如果我將我的循環刪除到我的主目錄中,那麼一切都會好的。SDL 1.2必須按兩次鍵以使事件生效

這裏是我的主循環:

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; 
     } 
    } 

這是我的函數(她還在進行中,所以不要感到震驚,如果它似乎LOOOOT愚蠢: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; 
      } 
    } 
} 
} 
+0

@MaKo已經在下面回答了這個問題,但只是在旁邊,使用'SDL_WaitEvent'只在特定情況下被建議,因爲它是一個阻塞函數。在大多數情況下,最好使用'SDL_PollEvent' – Zammalad

回答

4

據我瞭解,你有兩個(嵌套)事件循環,都使用他們的本地'連續'變量。當你進入內部循環時,按下逃逸從外部循環出來:你需要再次按Esc才能從循環中出來。

根據您的需要,一種可能的快速解決方案可能是如果玩家想要退出遊戲,則從遊戲()返回true或false來指示。就我個人而言,我認爲使嵌套的事件循環表現得很好可能會很麻煩(當它們大而深時),但很遺憾,在許多情況下,您無法避免它們。如果可以的話,小心他們。

+0

抱歉遲到(聖誕節等^^)。謝謝你,它通過改變函數返回類型int,並返回0,所以當我離開play()函數時,它也會在主體中更改「continuer」。 新年快樂 – DoT