Leo*_*ele 10 keyboard sdl input
我update()每秒运行一次方法来"更新"用户的键盘输入,以便稍后在程序的逻辑部分中读取它.所以我在SDL Docs中找到了两种实现方法,我不确定应该使用哪一种方法.
1; 使用SDL_PollEvent循环搜索关键/关闭事件并将关键状态保存在地图中,以便我可以检查程序逻辑中的每个关键状态.
注意:或者,我也可以使用SDL_PeepEvents而不是SDL_PollEvent来仅采用重要的事件类型; 所以,它不会"抛弃"队列中的事件.
std::map<int, bool> keyboard; // Saves the state(true=pressed; false=released) of each SDL_Key.
void update()
{
SDL_Event event;
while( SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = true;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
2; 每帧从键盘拍摄快照,以便我可以轻松阅读.
Uint8* keyboard;
void update()
{
SDL_PumpEvents();
keyboard = SDL_GetKeyState(NULL);
}
Run Code Online (Sandbox Code Playgroud)
通过以上任何实现,我可以keyboard像这样阅读:
if (key_map[SDLK_Return]) printf("Return has been pressed.");
Run Code Online (Sandbox Code Playgroud)
还有,还有另一种方法吗?
小智 9
我更喜欢做1的变化,我填充三个数组,不仅指示当前状态,还指示哪些键刚刚关闭以及哪些键刚刚上升.这允许我在代码中轻松检查这些事件(不与之前的快照比较),但最重要的是,它不会错过持续少于一帧的事件.例如,如果您的游戏由于机器速度较慢而以10 fps运行,则用户可能会在两次更新例程调用之间按下并释放一个重要的键,然后您的系统将永远不会注册它.这非常令人沮丧.
按住键时,SDL也会发送键事件,这样您就可以为每个键启用多个按键事件.我发现这在通过项目列表实现键盘滚动时特别有用,例如键盘控制的菜单.
你应该使用解决方案2.
为什么?正如SDL_GetKeyState()文档所指出的那样,在使用它之前,您需要调用SDL_PumpEvents()更新状态数组.
当你打电话时SDL_PollEvent(),它隐含地打电话SDL_PumpEvents().所以,SDL_GetKeyState()无论如何它基本上都会更新数组.通过手动解析这些事件,您只需创建第二个数组(实际上是一个慢得多的地图),其中包含SDL已经为您收集的相同信息.
所以,我敢说第一个解决方案意味着两次做同样的事情.如果您决定支持诸如重复击键(SDL_EnableKeyRepeat())之类的事情,那么您将重新实现SDL的更大部分.