好吧,我试图避免使用已弃用的 DirectInput。
但是我需要在游戏的每个“帧”或“迭代”中抢夺所有关键状态,以便我可以采取相应的行动。例如,如果玩家按下 VK_RIGHT 键,那么他将在该帧上向右移动一点点。
WM_INPUT 消息的问题在于,由于游戏循环的编写方式,它们每帧会出现不可预测的次数:
味精消息;
而(一)
{
if( PeekMessage( &message, NULL, 0, 0, PM_REMOVE ) )
{
如果(message.message == WM_QUIT)
{
休息 ; // 当 WM_QUIT 时保释
}
TranslateMessage( &message ) ;
DispatchMessage( &message ) ;
}
别的
{
// 没有消息,所以运行游戏。
更新() ;
画() ;
}
}
因此,如果在那里堆叠了多个WM_INPUT 消息,那么它们都将在 Update()/Draw() 之前得到处理。
我通过使用 BOOL 数组来记住哪些键已关闭,从而解决了这个问题:
bool array_of_keys_that_are_down[256];
案例 WM_INPUT :
if(它的键盘输入)
{
array_of_keys_that_are_down[VK_CODE] = TRUE;
}
这很好用,因为 Update() 函数检查
无效更新()
{
如果(array_of_keys_that_are_down[VK_RIGHT])
{
// 将玩家向右移动一点
}
}
但现在的问题是 WM_INPUT 消息生成的频率不够高。在第一次按下 VK_RIGHT 和随后的 VK_RIGHT 消息之间有大约 1 秒的延迟,即使玩家一直将手指放在它上面。它不像 DirectInput 那样你可以keyboard->GetDeviceState( 256, (void*)array_of_keys_that_are_down );(通过一次调用获取每帧的所有关键状态)
所以我迷路了。除了对我需要监视的每个键使用 GetAsyncKeystate() 函数调用之外,如果您不能可靠地抓取每帧的所有键状态,我认为没有办法避免使用 DirectInput。
在我看来 DirectInput 是解决这个问题的一个很好的解决方案,但如果它被弃用,那么真的必须有某种方法可以方便地仅使用 Win32 api 来做到这一点。
当前array_of_keys_that_are_down被重置为所有 FALSE 的每一帧。
memset(array_of_keys_that_are_down,0,sizeof(array_of_keys_that_are_down));
*编辑
我一直在解决这个问题,一个解决方案是只重置一个关键状态,一旦它被释放
案例 WM_INPUT :
if(它的键盘输入)
{
如果(它是按下)
array_of_keys_that_are_down[VK_CODE] = TRUE;
别的
array_of_keys_that_are_down[VK_CODE] = FALSE;
}
我不喜欢这个解决方案,因为它看起来很脆弱。如果用户在按下某个键时从应用程序中切换,那么该键将被“卡住”,直到他切换回来并再次按下相同的键,因为我们永远不会收到上行WM_INPUT消息。它会导致奇怪的“粘滞键”错误。