Чтение состояния клавиатуры приложения Win32 - PullRequest
0 голосов
/ 31 мая 2018

Я кодирую простой движок 3D-игр с DirectX11, и я использую 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 голосов
/ 31 мая 2018

Вам необходимо переместить чек !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, то есть (keys['O'] & 0x80 && !pressed) == true, поэтому рендерерпереключается, и pressed устанавливается в true.

Pass # 2: pressed==true, поэтому (keys['O'] & 0x80 && !pressed) == false, поэтому pressed устанавливается в false.

Pass # 3: pressed==false, так (keys['O'] & 0x80 && !pressed) == true, так что рендерер переключается, а pressed устанавливается в true.

И так до тех пор, пока вы в конечном итоге не отпустите 'O' ...

В новомcode, pressed устанавливается в true только тогда, когда keys['O'] & 0x80 впервые оценивается как true, и остается установленным в true, пока keys['O'] & 0x80 не оценивается как false.Затем переключается один раз, когда keys['O'] & 0x80 снова оценивается как true.И так далее ...

...