- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是一个相当不寻常的问题,但我需要一些关于 Win32 究竟如何处理不同的按键事件的解释。
WM_KEYDOWN
当您想要接收长按时使用,例如如果您在游戏中,并且想要前进,请按向上箭头键或“W”键,游戏中的角色会继续前进。由于 WM_KEYDOWN
,您不必多次按键。
我有一个基于 win32 的 3D OpenGL 应用程序,我在其中使用“W-A-S-D”和 箭头键
在 3D 世界中四处移动。它们都按照预期的方式工作。
也就是说,当我在 3D 世界中时,我能感觉到 Win32 处理 WASD
和箭头键的方式之间存在细微差别。
case UP_k:
f_zPosition-=CAM_MOVEMENT_SPEED;
break;
同样的代码也用于 case 'W':
。
但在游戏中,由于某些原因,箭头键的移动比 WASD
键的移动要流畅得多。
WASD
的移动像箭头键一样流畅。我想知道是否有人在 Win32 中注意到这一点,这是我的事件循环代码,按照评论中的要求。
do
{
window.displayGL();
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage (&msg);
}while(msg.message != WM_QUIT);
最佳答案
win32 应用程序上的正常消息处理循环调用两个函数:
TranslateMessage(&msg);
DispatchMessage(&msg);
第一个函数,TranslateMessage
查看虚拟键消息(例如 WM_KEYDOWN
消息),如果按下的键对应于字符键。如果您按住 'W'
键,由于自动重复功能,会生成很多 WM_KEYDOWN
。箭头键也是如此,但在 'W
' 的情况下,对于每个 WM_KEYDOWN
也会生成一个 WM_CHAR
,这是您的应用程序将不得不处理。
即使您的应用程序只是查看 WM_CHAR
并丢弃它们,由此产生的延迟也可能很明显,尤其是因为您每次处理 WM_KEYDOWN
时都会移动相机/p>
更多信息请查看this .
解决方案:
您应该使移动速度独立于处理输入的速度。有两种主要方法可以做到这一点:
在这两种情况下,在处理输入时不要移动角色。相反,当您收到 WM_KEYDOWN
时设置一个 bool 值 playerIsMoving
为 true
,并在获得 WM_KEYUP
时将其重置为 false
。然后仅当变量为 true
时,在生成下一帧时应用移动。
[更新]
看到主循环后:尝试像这样修改它:
修改一:注释掉TranslateMessage
。你不需要它,除非你想在你的应用程序中有文本框和类似的东西。
修改 2:添加一个单独的函数来更新世界状态。
do
{
UpdateWorld()
window.displayGL();
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
//TranslateMessage(&msg);
DispatchMessage (&msg);
}while(msg.message != WM_QUIT);
// I won't define exactly all of this, you can get an idea
// what I'm doing by the names. playerIsMoving should be set
// and reset in the `WindowProcedure` when processing 'WM_KEYDOWN/UP':
void UpdateWorld(){
float delta = timeSinceLastCall()
if(playerIsMoving)
player.pos += speed * delta;
}
关于c++ - WM_KEYDOWN 如何处理不同的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23862825/
MSDN 文档说 LParam 前 15 位用于重复计数,但它说它不是累积的 现在除非我在这里遗漏了一些东西,为什么它称它为重复计数但说它不是累积的? 这是一个矛盾的说法?它说它可以,但它没有?或者我
这个问题在这里已经有了答案: Keyboard Input & the Win32 message loop (2 个答案) 关闭 8 年前。 我正在尝试做一个非常简单的任务——当按下一个键时发生一
我目前正在尝试从我自己的 InputBox 的 WM_KEYDOWN 和 WM_CHAR 消息中获取键盘输入。 这是我用于基本输入的代码,它适用于字符: if(msg.message == WM_
我使用 WM_KEYDOWN/WM_KEYUP 定义了一些函数来处理输入,但似乎只有 WM_KEYUP 可以正常工作。当使用利用 WM_KEYDOWN 的函数时,什么也没有发生。 (不显示调试消息)
我有一个窗口可以创建许多其他常用控件,例如菜单、带有按钮和组合框的工具栏以及状态栏。问题是每当我按 Enter 或 Esc 时窗口都不会收到 WM_KEYDOWN 消息,但我需要处理这些消息。是否有任
我试图让我的应用程序在按下 CTRL+S 时执行某些操作。我只是不确定 W 和 L 参数如何为 WM_KEYDOWN 工作。 MSDN 有一些关于位域的内容,我不确定。如何检测 CTRL 和 S?谢谢
我一直在尝试找出程序中的错误。我注意到,每当我按住向上和向左箭头键并按空格键时,我的 WndProc 永远不会接收或处理 WM_KEYDOWN 消息以及 WPARAM 为 VK_SPACE。 我有点好
我试图让我的程序在按下 shift 键时切换 bool 值。但是,出于某种原因,它似乎没有收到消息,因为我已经将 MessageBoxes 放在 KEYDOWN 和 KEYUP 的情况下,并且它们没有
这是一个相当不寻常的问题,但我需要一些关于 Win32 究竟如何处理不同的按键事件的解释。 WM_KEYDOWN 当您想要接收长按时使用,例如如果您在游戏中,并且想要前进,请按向上箭头键或“W”键
我正在尝试通过 PostMessage 向一个应用程序发送击键。我正在使用 Spy++ 来尝试了解如何发送消息,因为我不完全了解其内部工作原理。 在这张图片中,第一个项目(选中的项目)是用我自己实际击
我正在尝试编写一个可以读取条码扫描仪的程序。此外,即使应用程序不是焦点窗口(即在系统托盘中运行等),我也需要它来读取输入。 我找到了这篇标题为 Distinguishing Barcode Scann
我有这个代码: public static void Next() { Process[] processes = Process.GetProcessesByName
win32 中是否有一个函数可以获取 CTRL、ALT 或大写锁定键的虚拟键代码并返回一个字符串“CTRL”、“ALT”、“CAPSLOCK”? 我只能接收 WM_KEYDOWN 消息,不能接收 WM
我正在编写一个可以将击键发送到另一个应用程序的应用程序。当我硬编码要发送的文本时,我有一些工作。但是,当我使用 argv[] 从参数列表中获取文本时,它不再发送文本,而是发送数字或什么都不显示。我认为
我需要有关 WM_KEYDOWN 的帮助,我想消除第一次按键和重复按键之间的“暂停”。 如果你持续按住一个按钮,我希望程序直接实现它。 我正在尝试使用 directx 制作游戏。请告诉我是否应该使用
如果 WM_KEYDOWN 有一个 messagebox() 以便理解这个案例的功能。 谁能帮我看看为什么这个case没 react ? 我正在尝试调试这个,同时我从键盘和调试器插入一些字母,但没有出
Win32 应用程序如何只响应第一个 WM_KEYDOWN 通知? MSDN 文档声称第 30 位“指定先前的 key 状态。如果在发送消息之前 key 已关闭,则值为 1,如果 key 已启动,则值
我刚开始MFC编程,之前没有做过任何UI设计和编程。我想知道为什么假设键盘正常工作,当每个被按下的键肯定会被释放时,Windows 会生成两条消息 WM_KEYUP 和 WM_KEYDOWN。 我认为
我在编辑框中处理 WM_KEYDOWN 消息。 我正在处理一堆键,但对于某些键(例如选项卡),我想阻止可显示字符附加到编辑框。 case WM_KEYDOWN: { switc
public class sendKeys { [DllImport("user32.dll")] public static extern IntPtr FindWindow(str
我是一名优秀的程序员,十分优秀!