Я написал небольшое приложение opengl на c ++, используя SDL2 для создания окон и обработки ввода.
Теперь у меня есть массивы логических значений, которые говорят, нажата ли соответствующая клавиша или нет.
static const int NUM_KEYS = 512;
static bool Inputs[NUM_KEYS];
static bool DownKeys[NUM_KEYS];
static bool UpKeys[NUM_KEYS];
Мой метод обновления ввода выглядит так:
SDL_GL_SwapWindow(m_window);
for(int i = 0; i < NUM_KEYS; i++)
{
g_DownKeys[i] = false;
g_UpKeys[i] = false;
}
while(SDL_PollEvent(&e))
{
if(e.type == SDL_QUIT)
{
m_isClosed = true;
}
switch(e.type)
{
case SDL_KEYDOWN:
g_DownKeys[e.key.keysym.sym] = true;
g_Inputs[e.key.keysym.sym] = true;
break;
case SDL_KEYUP:
g_UpKeys[e.key.keysym.sym] = true;
g_Inputs[e.key.keysym.sym] = false;
break;
default:
break;
}
}
if(g_Inputs[SDLK_w])
{
//this works just fine, because SDLK_w = 119
}
if(g_Inputs[SDLK_UP])
{
//this crashes the program, because SDLK_UP = 1073741906
}
Я также нашел список каждого ключа с его кодом:
http://wiki.libsdl.org/SDLKeycodeLookup
Как видите, я могу использовать только те клавиши на клавиатуре, которые имеют максимальный код клавиши 127 (десятичный).
Я также заметил, что SDL2 использует перечисление для клавиш, поэтому при наведении курсора SDLK_UP
Visual Studio показывает: enum <unnamed>::SDLK_UP = 1073741906
, но правильный путь таков: enum SDLKey::SDLK_UP = 1073741906
,
Итак, где-то отсутствует SDLKey.
Я думаю, что моя обработка ввода в порядке.
Как можно решить проблему с исключением индекса за пределами границ?
Поэтому я думаю, что должен решить проблему с помощью перечисления SDLKey.
Хорошо, если в ваших массивах 512 элементов, и вы обнаружите, что значение SDLK_UP
1073741906, вы не должны удивляться исключениям «индекс вне границ», верно? 🙂
SDL2 ввел различие между «кодами клавиш» и «кодами сканирования».
Скан-код представляет собой физическую клавишу на клавиатуре. Они получены из спецификации клавиатуры USB.
Код клавиши представляет собой глиф, который напечатан на клавиатуре. Код клавиши обычно является кодом Unicode символа, который напечатан на клавише, но специальные очень большие значения используются для не символьных клавиш, таких как клавиши со стрелками.
Там более подробная информация на SDL вики.
То, как написан ваш код, означает, что вы хотите использовать сканкоды. Итак, сначала:
static const int NUM_KEYS = SDL_NUM_SCANCODES;
Затем замените каждый случай keysym.sym
с
keysym.scancode
И, наконец, использовать SDL_Scancode константы:
SDL_SCANCODE_W
SDL_SCANCODE_UP
etc.
Я решил это с помощью SDL1.2
вместо SDL2
,
SDL2.lib
, SDL2main.lib
[, SDL2test.lib] изSDL.lib
а также SDLmain.lib
,SDL2.dll
из вашего проекта.SDL.dll
Теперь вы настроили SDL1.2.
SDL_Surface
вместо SDL_Window
, так далее…).Когда вы используете SDL1.2, вы можете найти недостающие enum SDL_Key
внутри SDL_keysym.h
,