Клавиша ввода запаздывает при использовании Windows API и WM_KEYDOWN C ++ - PullRequest
2 голосов
/ 16 марта 2012

Итак, я пытаюсь создать программу с использованием Windows API (и DirectX9, если это важно) и пытаюсь использовать WM_KEYDOWN и WM_KEYUP для получения ввода с клавиатуры. Это связанная часть моего кода прямо сейчас. Идея состоит в том, что массив «keyTimes» должен хранить количество кадров, которые удерживаются клавишей.

    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);


    Game* Game::s_instance = NULL;

    LPDIRECT3D9 d3dObject;
    LPDIRECT3DDEVICE9 d3dDevice;

    Game::Game(){
        for(int i=0; i<256; i++){
            keyTimes[i]=0;
        }

    }

    //....

    Game* Game::Instance(){
        if(Game::s_instance==NULL){
            s_instance = new Game();
        }
        return s_instance;
    }

    //Checks to see if key was pressed, and adds to value
    void Game::keyCheck(int keyNum, bool pressed){
        if(pressed){
            keyTimes[keyNum]++;
        }
        else{
            keyTimes[keyNum]=0;
        }

    }

    //Returns time that key has been pressed
    int Game::keyPressed(int keyNum){
            return keyTimes[keyNum];
    }

    //Returns true if key was hit once, and doesn't return true again until the key is let go and hit again.
    bool Game::keyHit(int keyNum){
        return keyTimes[keyNum]==1;
    }

    //Returns true only if the key has been held for delay
    bool Game::keyHeld(int keyNum, int delay){
        if(delay==0)
            delay=1;

        return keyTimes[keyNum]==delay;

    }

    //Returns true everyXFrame frames.
    bool Game::keyPressedDelay(int keyNum, int everyXFrame){
        if(everyXFrame<2){
            return false;
        }
        return keyTimes[keyNum]%everyXFrame==1;
    }


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){

    switch (message)
    {
            case WM_DESTROY:
                 PostQuitMessage(0);
            break;
            case WM_KEYDOWN:
                {
                    Game::Instance()->keyCheck(wParam,true);

                    return 0;   

                }
            break;
            case WM_KEYUP:
                {

                    Game::Instance()->keyCheck(wParam,false);
                    return 0;
                }
            break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;

}


    //........
    //Inside the main function while loop....


    if(Game::Instance()->keyHit(VK_LEFT)){
        thing->move(-3,0);
    }
    if(Game::Instance()->keyHit(VK_RIGHT)){
        thing->move(3,0);
    }
    if(Game::Instance()->keyHit(VK_UP)){
        thing->move(0,-3);
    }
    if(Game::Instance()->keyHit(VK_DOWN)){
        thing->move(0,3);
    }

    //.......

Поэтому, когда я пытаюсь использовать функцию «KeyPressed» в качестве логического значения для перемещения «вещи» в основной функции, она перемещается на три пикселя, останавливается примерно на полсекунды, а затем снова начинает двигаться. Это также остановится снова, если я попытаюсь нажать другую клавишу, удерживая нажатой первую. Когда я использую «KeyHit», чтобы переместить его, он идет около 9-12 пикселей, затем останавливается (вместо того, чтобы идти только 3).

Как бы я изменил свой код, чтобы функции работали как закомментированные, без каких-либо задержек?

РЕДАКТИРОВАТЬ 26/26/12: мне удалось исправить код. Оказывается, проблема была просто в том, что я использовал функцию GetMessage в своем основном цикле, который ждет ввода перед перемещением, где я должен был использовать PeekMessage.

Ответы [ 2 ]

4 голосов
/ 16 марта 2012

keyHit работает только в течение первых 500 миллисекунд, потому что срабатывает автоповтор и приводит к тому, что число обращений становится больше 1.

Добавьте некоторую отладочную трассировку, чтобы наблюдать, какие сообщения вы получаете и какое значениеkeyTimes - каждый раз, когда вы проверяете его в своей основной игровой петле.Это, вероятно, определит проблему.

1 голос
/ 19 марта 2012

Поэтому, когда я пытаюсь использовать функцию «KeyPressed» в качестве логического значения для перемещения «вещи» в основной функции, она перемещается на три пикселя, останавливается примерно на полсекунды, а затем начинает двигаться снова.

Это стандартное поведение Windows.

Например, если вы переходите на Панель управления Windows и в свойствах Клавиатура установите Повторите задержку на короткое время, вы увидите, что время задержки теперь сокращено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...