я из 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 (), и я не заметил разницы до сих пор, когда я попытался переместить мой квадрат с помощью стрелок на клавиатуре. Очевидно, что я не могу нажимать две клавиши со стрелками одновременно, так как цикл захватывает одно событие за раз.
И проблема в том, что в API нет такой вещи как «SDL_Event_Get ()». Только эти:
Ну, я не знаю, как Пит Шиннерс портировал SDL 1.2 на Python и обрабатывал события таким чудесным образом, поэтому мне трудно понять SDL 2.0 (я, вероятно, не единственный). Есть ли такая вещь, как «получить все события ()» в SDL 2.0? Что делать, если я хочу проверить, были ли нажаты ВСЕ возможные клавиши В ТО ЖЕ ВРЕМЯ?
Ты можешь использовать 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
, но в обоих случаях вам придется определить либо operator<
или же std::hash
для типа SDL_Event
,
Альтернативой является создание собственного универсального алгоритма, который работает с любым контейнером:
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))
// ...
но я не уверен, что это тебя покупает.