【发布时间】:2010-02-14 16:44:32
【问题描述】:
好吧,我试图避免使用已弃用的 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。
*编辑
我一直在解决这个问题,一个解决方案是只重置一个关键状态,一旦它被释放
案例 WM_INPUT : if(它的键盘输入) { 如果(它是按下) array_of_keys_that_are_down[VK_CODE] = TRUE; 别的 array_of_keys_that_are_down[VK_CODE] = FALSE; }我不喜欢这个解决方案,因为它看起来脆弱。如果用户在按下键时从应用程序中切换,那么该键将被“卡住”,直到他切换回来并再次按下相同的键,因为我们永远不会收到上击 WM_INPUT 消息。它会导致奇怪的“粘滞键”错误。
【问题讨论】:
-
为什么不直接捕获 WM_KEYDOWN 或 WM_KEYUP 消息?
-
嗯,同样的原因,真的 - 有一个延迟..
标签: c++ winapi directx directinput