为了抓住事件,我进入了我的主循环。如果玩家输入“1”,那么我调用函数play(),其中包含一个事件循环(用于移动等...)。 我真的不明白为什么,但我必须按两次ESCAPE才能离开游戏,而其他关键只是看起来没有被认出来。 如果我将循环删除到我的主程序中,那么一切正常。
这是我在主要的循环:
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;
}
}
这是我的功能(她还在进行中,所以如果看起来像A 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 :(得分:4)
据我所知,你有两个(嵌套的)事件循环,都使用他们的本地&#39;继续者&#39;变量。当你进入内部循环时,按下escape将从那个循环中移出到外部循环:你需要再次按esc从该循环中出来。
根据您的需要,可以采用一种可能的快速解决方案。从play()返回true或false以指示玩家是否想要退出游戏。就个人而言,我认为使嵌套事件循环表现得很好可能会很麻烦(当它们很大而且很深)时,但遗憾的是在很多情况下你无法避免它们。如果可以的话,要小心它们。