我正在开发C ++ DirectX 2D游戏,我需要输入键盘和鼠标 维基百科说:
Microsoft建议新应用程序使用Windows消息循环进行键盘和鼠标输入,而不是DirectInput
那我应该怎么用呢? 我有一个GameScreen类,它负责绘图和更新(游戏逻辑),我在Windows消息循环中调用Draw和Update方法。
由于
答案 0 :(得分:14)
由于您几乎必须运行消息泵以获得窗口,因此您也可以使用该泵来处理键盘和鼠标输入。无论您将键盘事件传递到子窗口,都完全取决于您的泵,如果您愿意,可以在泵中处理它们。
您的典型消息泵如下所示:
while (GetMessage(&msg, NULL, 0, 0))
{
if (WM_QUIT == msg.message)
break;
TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN
DispatchMessage(&msg); // this sends messages to the msg.hwnd
}
对于游戏,你的泵可能看起来更像这个
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
{
bool fHandled = false;
if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
fHandled = MyHandleMouseEvent(&msg);
else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
fHandled = MyHandleKeyEvent(&msg);
else if (WM_QUIT == msg.message)
break;
if ( ! fHandled)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// if there are no more messages to handle right now, do some
// game slice processing.
//
}
}
当然,您的实际泵可能会比这更复杂,可能使用MsgWaitForMultipleObjects
,这样即使没有要处理的消息也可以定期唤醒,但是当有消息时立即唤醒。
答案 1 :(得分:5)
DirectInput已被弃用,原因很充分。据我所知,它创建了一个额外的线程,只是查询Windows'Raw Input界面。为了获得最佳性能,我将直接使用Raw Input。
如果性能对您来说不是问题(我猜这是当前硬件上的2D游戏的情况),请遵循Microsoft的建议并使用窗口消息,如John Knoeller所述。
答案 2 :(得分:3)
仅供参考:John Knoeller的回答......一个简单的消息泵看起来像这样:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
他包含的WM_QUIT测试永远不会为真,因为GetMessage在收到WM_QUIT时返回零。但是,在PeekMessage循环中测试WM_QUIT是,因为PeekMessage返回true / false是否返回了消息。由于GetMessage会阻塞,直到返回一条消息,因此它可以有不同的返回值。
答案 3 :(得分:1)
如果游戏只有一个窗口,那么就我所知,这种区别纯粹是一种品味问题。但是,如果你已经(或者计划拥有或者不能积极排除将来拥有多个窗口的选项),那么Windows消息传递可能会让人厌烦。
问题在于,默认情况下,键盘/鼠标消息仅被路由到当前焦点的窗口,并且通常在您希望能够切换焦点的游戏中(到高分视图,雷达视图上的敌人等)和仍然保持互动性。简单的解决方案是每个需要键盘/鼠标输入的模块直接查询它,而不依赖于消息转发 - 因此,DirectInput。
我当然不能说你的具体情况 - 只是我的2c。
答案 4 :(得分:1)
是的,MSDN帖子是正确的。使用Windows消息,您可以使用多语言支持(用户可能正在使用的任何类型的键盘)/用户的个人设置(鼠标右键而不是左键)等等。您必须丢弃以使用DirectInput / XInput 。 仅将这2个用于游戏手柄/操纵杆支持。其余的只需使用Windows消息。
详情我同意John Knoeller的回答。
答案 5 :(得分:0)
在特殊情况下使用“仅使用直接输入”
与getmessage一起使用的Windows消息循环的好处是它使用0%的cpu使用率。如果您正在进行非处理器密集型操作,例如等待用户输入密钥,从用户收集数据(如数据库或税务程序),甚至是文字处理程序,那么只需将Windows消息与getmessage一起使用即可。我所有上述程序日期都是用户按键时的过程。
Windows消息循环需要处理密钥的所有内容都是为了切换到该程序。鼠标甚至不需要在窗口中。
特殊情况 - 使用directinput
如果您需要: 1)知道按下和释放按键的时间。您也可能不希望重复检测到按键作为按键 2)当另一个程序切换到后台时,在后台处理密钥。
如果上述任何一种情况属实,则使用directinput。
如果您只是从用户那里收集数据,那么您将需要使用sleep命令暂停程序的执行。如果程序只是坐在那里等待来自用户的密钥,您希望程序在任务管理器中具有0%的CPU使用率。
使用sleep函数将程序置于睡眠状态,直到您想要轮询直接输入键为止。
因此,直接输入只会浪费编程时间,如果你正在做一个简单的普通任务,就像你看到的那样从用户那里收集密钥。
答案 6 :(得分:-1)
XInput绝对是最佳选择。低延迟输入对于游戏至关重要,XInput(在新的DirectXSDK中替换DirectInput)专门针对这些用例而设计。
此外,您还可以支持开箱即用的游戏控制器,操纵杆等。