SDL_GetKeyboardState无法正常工作

我正在尝试为SDL 2的游戏制作一个控制器(不想在gamedev上询问,因为它不是直接的游戏问题)我使用SDL_GetKeyboardEvent来查看导航箭头是否被按下但是它显然不起作用,如果按下其中一个键,它应该打印一个值1或-1但它不会打印0即使我按住键几秒钟,它就像它没有检测到键被压了。 我搜索了整个互联网,这就是他们如何做到的,但它对我不起作用。

#define SDL_MAIN_HANDLED #include  #include "SDL.h" /* I'll add some code later so something that isn't used might be initialized */ int main (void) { int a = 1; int x; int z; SDL_Event quit; const Uint8 *keys = SDL_GetKeyboardState(NULL); SDL_Init(SDL_INIT_VIDEO); while(a) { SDL_PollEvent(&quit); if(quit.type == SDL_QUIT) a = 0; if(keys[SDL_SCANCODE_UP]) z = 1; else if(keys[SDL_SCANCODE_DOWN]) z = -1; else z = 0; if(keys[SDL_SCANCODE_LEFT]) x = -1; else if(keys[SDL_SCANCODE_RIGHT]) x = 1; else x = 0; printf("%d, %d\n", x, z); //This is supposed to print //x, z values so if up arrow is pressed it will print 0, 1 and if //down arrow is pressed it will print 0, -1: the same with horizontal ones. //1 or -1, 1 or -1 } SDL_Quit(); return 0; } 

您似乎只更新键盘状态一次

 SDL_GetKeyboardState(NULL); 

应该在循环中使用。

尽管如此,输入管理通常是这样做的:

 switch(quit.type) { case SDL_KEYDOWN: switch(quit.key.keysym.sym) { case SDLK_ESCAPE: //quit case SDLK_UP: //up arrow break; case SDLK_DOWN: //down arrow break; case SDLK_RIGHT: //right arrow break; case SDLK_LEFT: //left arrow break; default : break; } case SDL_KEYUP ... 

而不是在每一帧都获得所有键盘,你看起来改变了什么。

此外,您不应在不限制帧速率的情况下使用SDL_PollEvent。

阅读文档: wiki

Note: This function gives you the current state after all events have been processed, so if a key or button has been pressed and released before you process events, then the pressed state will never show up in the SDL_GetKeyboardState() calls

这意味着什么?

您需要处理所有事件。 怎么样? 在循环之后循环PollEvent (或者如果你想检查循环,最后检查), SDL_GetKeyboardState是可用的。

所以,通过循环,检查键盘状态。 在检查钥匙之前,不要忘记总是经历循环

例如

 while (game) { /*! updates the array of keystates */ while ((SDL_PollEvent(&e)) != 0) { /*! request quit */ if (e.type == SDL_QUIT) { game = false; } } if (keys[SDL_SCANCODE_RIGHT]) std::cout << "Right key"; } 

这是我的InputManager更新function,用于更新键盘和鼠标的用户输入。 注意const_cast需要能够更新类变量Uint8* keysArray; 。 这样,可以一次处理多个事件。

  void update() { SDL_PumpEvents(); // update keyboard state keysArray = const_cast  (SDL_GetKeyboardState(NULL)); if (keysArray[SDL_SCANCODE_RETURN]) printf("MESSAGE:  is pressed...\n"); if (keysArray[SDL_SCANCODE_RIGHT] && keysArray[SDL_SCANCODE_UP]) printf("MESSAGE: Right and Up arrows are pressed...\n"); // update mouse location and button states SDL_GetMouseState(&x, &y); getMouseButtonStates(); }