读取键盘状态Win32应用程序

时间:2018-05-31 15:50:49

标签: winapi input keyboard

我用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'键来切换我的渲染器在释放后再次按下它时重新切换它,但代码会不断检测到该键。我做错了什么?

1 个答案:

答案 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再次评估为真时切换一次。等等...