我正在开发一个C++的DirectX 2D游戏,需要使用键盘和鼠标输入。
维基百科上说:
微软建议新应用程序使用Windows消息循环处理键盘和鼠标输入,而不是DirectInput
那么我该怎么用呢?
我有一个GameScreen类来处理绘图和更新(游戏逻辑),我在Windows消息循环中调用Draw和Update方法。
谢谢
我正在开发一个C++的DirectX 2D游戏,需要使用键盘和鼠标输入。
维基百科上说:
微软建议新应用程序使用Windows消息循环处理键盘和鼠标输入,而不是DirectInput
那么我该怎么用呢?
我有一个GameScreen类来处理绘图和更新(游戏逻辑),我在Windows消息循环中调用Draw和Update方法。
谢谢
由于必须运行消息泵才能拥有窗口,因此您可以使用该泵来处理键盘和鼠标输入。如何处理键盘事件取决于您的消息泵,您可以将其传递给子窗口,或者如果愿意,也可以在消息泵中处理它们。
您典型的消息泵看起来像这样:
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
}
对于一个游戏,你的Pump可能看起来更像这样:
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
,这样即使没有消息要处理,你也可以周期性地唤醒,但是当有消息时应立即处理。DirectInput已被弃用,原因充分。据我所知,它会创建一个额外的线程并且只是查询Windows的Raw Input接口。为了获得最佳性能,我建议直接使用Raw Input。
如果性能对您不是问题(我猜这是当前硬件上2D游戏的情况),请遵循Microsoft的建议并使用窗口消息,如John Knoeller所述。
参考信息:关于John Knoeller的回答... 一个简单的消息泵看起来像这样:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
是的,MSDN的帖子是正确的。使用Windows消息,您可以使用多语言支持(用户可能使用任何类型的键盘)/用户的个人设置(鼠标右键而不是左键)等,这些都必须舍弃以使用DirectInput / XInput。 只需使用这两个来支持游戏手柄/操纵杆。对于其余部分,请使用Windows消息。
关于细节,我同意John Knoeller的答案。
仅在特殊情况下使用DirectInput
使用getmessage的Windows消息循环非常好,因为它使用0%的CPU占用率。如果您正在进行不需要大量处理器的操作,例如等待用户的按键、从用户收集数据(例如数据库或税务程序)甚至是文字处理器等,那么使用Windows消息和getmessage就是明智的选择。在上述所有程序中,当用户按下键时,日期就成为了进程。
Windows消息循环处理按键所需的全部内容就是将该程序切换到。鼠标甚至不需要在窗口内。
特殊情况-使用DirectInput
如果您需要: 1)知道何时按下和释放键。您可能也不希望检测到重复的按键作为按键。 2)在切换到另一个程序时在后台处理键。
如果上述条件之一成立,则使用DirectInput。
如果您只是从用户收集数据,则需要使用“休眠”命令暂停程序的执行。如果程序只是在那里等待用户按键,则希望在任务管理器中将程序的CPU使用率降至0%。
使用睡眠函数将程序置于休眠状态,直到您想要轮询直接输入的按键。XInput绝对是正确的选择。低延迟输入对于游戏至关重要,而XInput(在新的DirectX SDK中替代DirectInput)正是为这些用例而设计的。
此外,您还可以直接使用游戏控制器、操纵杆等设备。