gpt4 book ai didi

c - SDL 1.2 必须按两次键才能使事件生效

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:27 26 4
gpt4 key购买 nike

为了捕获事件,我在 main 中设置了一个循环。如果玩家输入“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;
}
}

这是我的功能(她仍在进行中,所以如果它看起来很愚蠢,请不要感到震惊 :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;
}
}
}
}

最佳答案

据我所知,您有两个(嵌套的)事件循环,都使用它们的本地“continuer”变量。当您进入内层循环时,按 escape 键从内层循环跳出到外层循环:您需要再次按 esc 键才能退出该循环。

根据您的需要,一种可能的快速解决方案可能是例如从 play() 返回 true 或 false 以指示玩家是否要退出游戏。我个人认为让嵌套的事件循环表现得很好可能会很麻烦(当它们又大又深时),但遗憾的是在许多情况下你无法避免它们。如果可以,请小心对待它们。

关于c - SDL 1.2 必须按两次键才能使事件生效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27638427/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com