SDL的事件处理错误

时间:2014-02-28 12:44:48

标签: c++ events sdl

我正在使用SDL和C ++进行蛇游戏,我发现了一个涉及事件的错误。

在这个游戏中,现在有两个重要的功能:游戏功能(游戏的“主要”功能)和暂停功能。按下P键时,播放功能调用并执行暂停功能。在其中,您有两种可能性:继续或退出游戏。

现在,这是问题所在。当我尝试单击“继续游戏”时,游戏会暂时闪烁并返回暂停菜单。当我按住鼠标按钮时,我意识到游戏本身被冻结,直到发生任何类型的事件。如果是这样,它就会回到原来的位置。

经过一些测试后,我还注意到该错误是由SDL_PollEvent函数引起的。所以我在播放功能中将此功能更改为SDL_WaitEvent,当我要求他将游戏放回原处。但是,还会产生另一个问题:因为在我的播放功能中,有一个使用SDL_GetTicks的计时器,游戏需要一个触发事件才能流畅。例如,当我不断向任何方向移动光标时,游戏就可以运行。当我停下来时,它会冻结。

有没有办法解决这个错误?

这是播放功能中的事件处理程序:

SDL_PollEvent(&event); // Handle events
switch(event.type)
{
    case SDL_QUIT:
        quit = true;
        break;
    case SDL_KEYDOWN:
        switch(event.key.keysym.sym) // Change direction at certain key press
        {
            case SDLK_s:
                currentDirection = SNAKE_DOWN;
                break;
            case SDLK_w:
                currentDirection = SNAKE_UP;
                break;
            case SDLK_a:
                currentDirection = SNAKE_LEFT;
                break;
            case SDLK_d:
                currentDirection = SNAKE_RIGHT;
                break;
            case SDLK_ESCAPE: // Quit if escape key pressed
                quit = true;
                break;
            case SDLK_p:
                if (pause(screen) == false)
                    quit = true;
                    break;
                break;
            default: ; // Code to block the compiler's -Wall flag (does not do anything to the program itself)
        }
        break;
}

这是完整的暂停功能:

bool pause(SDL_Surface *screen)
{
    SDL_Surface *pauseMessage, *continueButton, *quitButton;
    SDL_Rect posPauseMessage, posContinueButton, posQuitButton;
    TTF_Font *fipps;
    SDL_Color color = {255, 255, 255};
    SDL_Event event;
    int x = 0, y = 0;
    bool quit = false, returnFalse = false;

    fipps = TTF_OpenFont("fipps.ttf", 50);
    pauseMessage = TTF_RenderText_Blended(fipps, "PAUSED", color);
    continueButton = TTF_RenderText_Blended(fipps, "Continue Game", color);
    quitButton = TTF_RenderText_Blended(fipps, "Exit to menu", color);

    posPauseMessage.x = (screen->w - pauseMessage->w) / 2;
    posPauseMessage.y = 200;

    posContinueButton.x = (screen->w - continueButton->w) / 2;
    posContinueButton.y = posPauseMessage.y + 200;

    posQuitButton.x = (screen->w - quitButton->w) / 2;
    posQuitButton.y = posContinueButton.y + 100;

    while (!quit)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                returnFalse = true;
                quit = true;
                break;
            case SDL_MOUSEBUTTONUP:
                x = event.button.x;
                y = event.button.y;

                if ((x > posContinueButton.x) && (x < posContinueButton.x + continueButton->w) && (y > posContinueButton.y) && (y < posContinueButton.y + continueButton->h))
                    quit = true;
                else if ((x > posQuitButton.x) && (x < posQuitButton.x + quitButton->w) && (y > posQuitButton.y) && (y < posQuitButton.y + quitButton->h))
                    returnFalse = true;
                    quit = true;

                break;
        }

        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
        SDL_BlitSurface(pauseMessage, NULL, screen, &posPauseMessage);
        SDL_BlitSurface(continueButton, NULL, screen, &posContinueButton);
        SDL_BlitSurface(quitButton, NULL, screen, &posQuitButton);
        SDL_Flip(screen);
    }

    TTF_CloseFont(fipps);
    SDL_FreeSurface(pauseMessage);
    SDL_FreeSurface(continueButton);
    SDL_FreeSurface(quitButton);

    if (returnFalse)
        return false;

    return true;
}

1 个答案:

答案 0 :(得分:0)

感谢@jordsti,我找到了一个解决方案:我需要将SDL_PollEvent作为while循环的条件,其中包含switch块。