我正在尝试使用SDL 2.0.1开发一个强大的游戏输入系统。我希望没有任何输入滞后。
我曾经使用SDL_GetKeyboardState()
执行此操作,但我切换到使用SDL_Event
和SDL_PollEvent()
为键盘,鼠标和操纵杆输入提供了统一的界面(所有内容都通过事件完成)
这样可以正常工作,但是如果我想在按住键时想要连续输入(例如移动一个字符),那么在SDL注意到该键被重复之前会有一点延迟。
在SDL 1.2中,可以使用函数调用设置此延迟。现在它不再是(据我所知)。
如何删除此延迟?我应该切换回直接读取键盘状态吗?
供参考,以下是我目前的输入方式......
SDL_Event sdlEvent;
while (running)
{
SDL_PollEvent(&sdlEvent);
switch (sdlEvent.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
printf("Key down!\n");
break;
default:
break;
}
}
应用程序打印"Key down!"
,然后打印一小段时间(大约一秒钟),然后重复打印,直到密钥被释放。
那么如何摆脱这种延迟?
答案 0 :(得分:4)
由于您未获得SDL_KEYUP
,因此只有bool
true
才能获得SDL_KEYUP
SDL_Event sdlEvent;
while (running)
{
bool keyDown = false;
while ( SDL_PollEvent(&sdlEvent) )
{
switch (sdlEvent.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
keyDown = true;
break;
case SDL_KEUP:
keyDown = false;
break;
default:
break;
}
}
if ( keyDown )
printf("Key down!\n");
}
当然,您需要存储所有键的内容,例如数组。 (或者甚至更好;将C++
与std::map
一起使用)然后您可以使用SDL_Keycode
(event.key.keysym.sym
)作为密钥。
答案 1 :(得分:2)
首先,您应该将事件轮询到循环中,否则每帧只会获得一个事件 所以
SDL_Event sdlEvent;
while (running)
{
while(SDL_PollEvent(&sdlEvent))
{
switch (sdlEvent.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
printf("Key down!\n");
break;
default:
break;
}
}
}
并且,为了处理您的Key Delay,应该创建一个按下了键的结构,以及按键启动时的时间戳。您可以将这些结构放入向量中,然后在为此键获取密钥时将其删除。并且为了处理键延迟,只需按下键,然后检查当前时间戳和键下行初始时间戳之间的差异。
答案 2 :(得分:1)
正如所提到的here,使这项工作跨平台的正确程序是使用SDL密钥状态而不是事件:
const Uint8* keystates = SDL_GetKeyboardState(NULL);
if(keystates[SDL_SCANCODE_DOWN])
{
printf("Key down!\n");
}
通过这种方式,您可以绕过任何基于操作系统的键盘延迟。 完整的教程: http://lazyfoo.net/tutorials/SDL/18_key_states/index.php