如何获得"列表" SDL 2.0中实时发生的所有事件?

时间:2015-04-30 05:16:15

标签: c++ pygame sdl sdl-2

我来自Pygame,在那里我有pygame.event.get(),它返回了所有事件的列表(所以,一旦我在主循环中有了事件列表,我就可以检查多个按键或无论是实时的,因为所有可能的事件都是可用的。)

现在这里是我的代码:

#include "init.h"
#include "texture.h"

int main(int argc, char** argv) {

    Init();

    while (running) {
        while (SDL_PollEvent(&e) != 0) { // PROBLEM <<< I don't want "POLL".
            auto key = e.key.keysym.sym;
            if (e.type == SDL_QUIT) {
                running = false;
            } else if (e.type == SDL_KEYDOWN) {
                if (key == SDLK_ESCAPE) {
                    running = false;
                }
                if (key == SDLK_UP) {
                    square_rect.y -= PLAYER_SPEED;
                } else if (key == SDLK_DOWN) {
                    square_rect.y += PLAYER_SPEED;
                } else if (key == SDLK_LEFT) {
                    square_rect.x -= PLAYER_SPEED;
                } else if (key == SDLK_RIGHT) {
                    square_rect.x += PLAYER_SPEED;
                }
            }

        }

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderFillRect(renderer, &square_rect);
        SDL_RenderPresent(renderer);

    }

    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

在我到目前为止看到的教程中,他们使用过SDL_PollEvent(),直到现在我才注意到差异,当时我试图用键盘箭头移动我的方块。显然,我不能同时按下两个箭头键,因为循环一次捕获一个事件。

问题是,&#34; SDL_Event_Get()&#34;在API中。只有这些:

好吧,我不知道Pete Shinners如何将SDL 1.2移植到Python并以如此奇妙的方式处理事件,所以我很难理解SDL 2.0(我可能很可能不是唯一的一个)。是否有&#34;得到所有的事件()&#34;在SDL 2.0中?如果我想检查是否按下了所有可能的键同时,该怎么办?

1 个答案:

答案 0 :(得分:3)

您可以按the documentation

中所述使用SDL_GetKeyboardState
const Uint8 *state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_RETURN]) {
    printf("<RETURN> is pressed.\n");
}
if (state[SDL_SCANCODE_RIGHT] && state[SDL_SCANCODE_UP]) {
    printf("Right and Up Keys Pressed.\n");
}

一般来说,您可以将事件提取到任何容器中,然后检查是否有任何数量的事件在这样的容器中。一个好的容器是std::setstd::unordered_set,但在这两种情况下,您都必须为类型operator<定义std::hashSDL_Event。< / p>

另一种方法是制作适用于任何容器的通用算法:

template<typename OutIt>
void push_events(OutIt out) {
    SDL_Event e;
    while (SDL_PollEvent(&e) != 0)
        *out++ = e;
}

然后将其应用于某个容器,例如std::vector

std::vector<SDL_Event> vector;
push_events(std::back_inserter(vector));

另一种选择是按下你自己的std::set键,在其中“记住”在任何给定时刻按下的键。

例如,给定:

std::set<SDL_Keycode> keys;

然后:

SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
    switch (e.type) {
    case SDL_KEYDOWN:
        auto key = e.key.keysym.sym;
        keys.insert(key);
        break;
    case SDL_KEYUP:
        auto key = e.key.keysym.sym;
        keys.erase(key);
        break;
    }
}

然后通过以下方式检查:

if (keys.count(SDLK_SPACE) && keys.count(SDLK_UP))
    // ...

但我不确定是什么让你买的。