如何在 SDL 2.0 中实时获取所有事件的 "list"?
How do I get a "list" of ALL the events in real time in SDL 2.0?
我来自 Pygame, and there I had 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(),直到现在,当我尝试使用键盘箭头移动我的方块时,我才注意到其中的区别。显然,我不能同时按下两个箭头键,因为循环一次捕获一个事件。
问题是,API 中没有 "SDL_Event_Get()" 这样的东西。只有这些:
嗯,我不知道 Pete Shinners 如何将 SDL 1.2 移植到 Python 并以如此奇妙的方式处理事件,所以我很难理解 SDL 2.0(我可能不是唯一的)。 SDL 2.0中有"get all the events ()"这样的东西吗?如果我想检查是否所有可能的键都在同一时间被按下怎么办?
您可以按照 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::set
或 std::unordered_set
,但在这两种情况下,您都必须为类型 SDL_Event
定义 operator<
或 std::hash
。
另一种方法是制作您自己的适用于任何容器的通用算法:
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
键被按下,其中 "remember" 在任何给定时刻按下了哪些键。
例如,给定:
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))
// ...
但我不确定你买的是什么。
我来自 Pygame, and there I had 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(),直到现在,当我尝试使用键盘箭头移动我的方块时,我才注意到其中的区别。显然,我不能同时按下两个箭头键,因为循环一次捕获一个事件。
问题是,API 中没有 "SDL_Event_Get()" 这样的东西。只有这些:
嗯,我不知道 Pete Shinners 如何将 SDL 1.2 移植到 Python 并以如此奇妙的方式处理事件,所以我很难理解 SDL 2.0(我可能不是唯一的)。 SDL 2.0中有"get all the events ()"这样的东西吗?如果我想检查是否所有可能的键都在同一时间被按下怎么办?
您可以按照 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::set
或 std::unordered_set
,但在这两种情况下,您都必须为类型 SDL_Event
定义 operator<
或 std::hash
。
另一种方法是制作您自己的适用于任何容器的通用算法:
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
键被按下,其中 "remember" 在任何给定时刻按下了哪些键。
例如,给定:
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))
// ...
但我不确定你买的是什么。