我用DirectX11编写一个简单的3D游戏引擎,我正在使用Win32 API读取用户输入(暂时,我将切换到DirectInput)。 要读取键盘上的键状态,我使用以下API函数:
void Game::ProcessInput()
{
unsigned char keys[256];
GetKeyboardState(keys);
Input::GetInstance()->ProcessKeyboardInput(keys, mCamera, *mEntity, *mRenderer);
}
我在游戏循环中调用它并将关键状态数组传递给我的Input类:
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'键来切换我的渲染器在释放后再次按下它时重新切换它,但代码会不断检测到该键。我做错了什么?
答案 0 :(得分:0)
您需要在!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
,从而切换渲染器:
传递#1:pressed==false
,所以(keys['O'] & 0x80 && !pressed) == true
,因此切换渲染器并将pressed
设置为true。
传递#2:pressed==true
,所以(keys['O'] & 0x80 && !pressed) == false
,因此pressed
设置为false。
传递#3:pressed==false
,所以(keys['O'] & 0x80 && !pressed) == true
,因此切换渲染器并将pressed
设置为true。
依此类推,直到你最终发布'O'
...
在新代码中,pressed
仅在keys['O'] & 0x80
第一次计算为true时设置为true,并且在keys['O'] & 0x80
计算为false之前保持设置为true。然后在keys['O'] & 0x80
再次评估为真时切换一次。等等...