winapi - 读取键盘状态 Win32 应用程序
问题描述
我正在使用 DirectX11 编写一个简单的 3D 游戏引擎,并且我正在使用 Win32 API 来读取用户输入(暂时,稍后我将切换到 DirectInput)。要读取键盘上按键的状态,我使用以下 API 函数:
void Game::ProcessInput()
{
unsigned char keys[256];
GetKeyboardState(keys);
Input::GetInstance()->ProcessKeyboardInput(keys, mCamera, *mEntity, *mRenderer);
}
我在我的游戏循环中调用它并将键状态数组传递给我的输入类:
void Input::ProcessKeyboardInput(unsigned char *keys, Camera &camera, Entity &player, Renderer &renderer)
{
static bool pressed = false;
/* update camera position - translate camera */
if (keys['A'] & 0x80)
camera.MoveRight(-speed);
if (keys['D'] & 0x80)
camera.MoveRight(speed);
if (keys['W'] & 0x80)
camera.MoveForward(speed);
if (keys['S'] & 0x80)
camera.MoveForward(-speed);
if (keys['Q'] & 0x80)
camera.MoveUp(speed);
if (keys['E'] & 0x80)
camera.MoveUp(-speed);
if (keys['P'] & 0x80)
speed == SLOW ? speed = FAST : speed = SLOW;
/* move player */
if (keys[VK_LEFT] & 0x80)
player.Rotate(-playerSpeed * 10.0);
if (keys[VK_RIGHT] & 0x80)
player.Rotate(playerSpeed * 10.0);
if (keys[VK_UP] & 0x80)
player.MoveForward(playerSpeed);
if (keys[VK_DOWN] & 0x80)
player.MoveForward(-playerSpeed);
if (keys[VK_SPACE] & 0x80)
player.Jump();
/* control rendering */
if (keys['O'] & 0x80 && !pressed)
{
renderer.TogglePostProcessing();
pressed = true;
}
else
pressed = false;
}
我认为我可以通过检查最高位(0x80 位掩码)来检测键是否被按住,这适用于移动键,但我希望“O”键在我按下它并重新切换时切换我的渲染器-当我释放它后再次按下它时切换它,但代码不断检测到键。我究竟做错了什么?
解决方案
您需要将!pressed
支票移动到if
块内,而不是if
本身:
if (keys['O'] & 0x80) {
if (!pressed) {
renderer.TogglePostProcessing();
pressed = true;
}
}
else
pressed = false;
在您的原始代码中:
if (keys['O'] & 0x80 && !pressed)
{
renderer.TogglePostProcessing();
pressed = true;
}
else
pressed = false;
'O'
按住 时,您会不断地来回切换,pressed
从而切换渲染器:
Pass #1: pressed==false
, so (keys['O'] & 0x80 && !pressed) == true
,所以渲染器被切换并pressed
设置为 true。
Pass #2: pressed==true
, so (keys['O'] & 0x80 && !pressed) == false
, sopressed
设置为 false。
Pass #3: pressed==false
, so (keys['O'] & 0x80 && !pressed) == true
,所以渲染器被切换并pressed
设置为 true。
依此类推,直到你最终释放'O'
......
在新代码中,pressed
仅当keys['O'] & 0x80
第一次评估为 true 时才设置为 true,并保持设置为 true 直到keys['O'] & 0x80
评估为 false。keys['O'] & 0x80
然后在再次评估为真时切换一次。等等...
推荐阅读
- azure-devops - 我得到“字段‘活动’包含不在支持值列表中的值‘实验’。” 尝试在 ADO 中创建任务时
- java - 列表中的搜索字段 @IndexedEmbedded
- xamarin - C#从非异步方法调用时等待所有异步任务完成
- javascript - 在网络搜索结果中显示 html 和 javascript 代码
- python - 从数据集中的值获取列标签
- prometheus - Prometheus 服务因无效参数错误而失败
- javascript - 如何通过使用 jstree 选择父节点来创建子节点?
- spring-tool-suite - 为 Spring Tools 4.3.9.14.CI 安装 Spring Tools 3 add on 的问题
- python - 在 Anaconda 中使用 Python3.6 后无法安装 Spyder 4.1.4
- javascript - 单击具有相同 id 的 div