如何找出在c ++中按下按键的时间?

时间:2019-06-27 13:54:36

标签: c++

我正在为我的学校项目创建一个涉及弹丸运动的游戏。我想通过确定按下某个键多长时间来获取角度值的输入。然后,代码应提供一个等于按下按键时间的角度值。有什么建议或想法吗?

1 个答案:

答案 0 :(得分:1)

您需要一种以非阻塞方式获取按键状态的方法。

在标准c ++库中无法实现此目的,因此您需要使用某种库/框架,其中有很多。

如果您使用的是Windows,一种方法是直接与OS API交互,从而直接从Windows队列中获取应用程序中的关键事件。

这是一个小示例,其中应用程序等待三秒钟,然后打印在那三秒钟内发生的关键事件以及生成事件的key

#include <stdio.h>
#include <iostream>
#include <vector>
#include <windows.h>
#include <thread>
#include <chrono>

#define MAX_INPUT_EVENTS 100

int main()
{
    //Handle to console input buffer
    HANDLE g_console_handle;
    //Return dword
    DWORD ret, ret_aux;
    //Input event structure
    INPUT_RECORD input_event[ MAX_INPUT_EVENTS ];
    //return flag
    bool f_ret;


    std::cout << "press some keys while the process waits 3 seconds...\n";

    std::this_thread::sleep_for( std::chrono::milliseconds(3000) );

    //get handle to console
    g_console_handle = GetStdHandle( STD_INPUT_HANDLE );

    //Get number of pending input events
    f_ret = GetNumberOfConsoleInputEvents( g_console_handle, &ret );
    //if: fail
    if (f_ret == false)
    {
        std::cerr << "ERR: could not get number of pending input events\n";
        return true; //Fail
    }
    //if: at least one event has been detected
    if (ret > 0)
    {
        //if: above processing limits
        if (ret >= MAX_INPUT_EVENTS)
        {
            std::cerr << "ERR: too many input events\n";
            return true; //Fail
        }
        //Get all the input event
        f_ret = ReadConsoleInput
        (
            g_console_handle,
            input_event,
            ret,
            &ret_aux
        );
        //for: every input event
        for (DWORD t = 0;t < ret_aux; t++)
        {
            //switch: Decode event type
            switch(input_event[t].EventType)
            {
                //case: keyboard
                case KEY_EVENT:
                {
                    //Structure holding key event
                    KEY_EVENT_RECORD &event = input_event[t].Event.KeyEvent;
                    //List of virtual keys
                    //https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes
                    //true=down, pressed
                    if (event.bKeyDown == true)
                    {
                        std::cout << "Virtual key: " << event.wVirtualKeyCode << " is down\n";
                    }
                    //false = up, released
                    else
                    {
                        std::cout << "Virtual key: " << event.wVirtualKeyCode << " is up\n";
                    }

                    break;
                }
                //unhandled input event
                default:
                {
                    //do nothing
                }
            }   //end switch: Decode event type
        }   //end for: every input event
    }   //end if: at least one event has been detected
    //if: no event detected
    else
    {

    }
}

这是输出,一个列表

press some keys while the process waits 3 seconds...
Virtual key: 68 is down
Virtual key: 65 is down
Virtual key: 68 is up
Virtual key: 65 is up
Virtual key: 68 is down
Virtual key: 68 is up
Virtual key: 65 is down
Virtual key: 70 is down
Virtual key: 87 is down
Virtual key: 70 is up
Virtual key: 65 is up
Virtual key: 70 is down
Virtual key: 87 is up
Virtual key: 70 is up

Process returned 0 (0x0)   execution time : 3.046 s
Press any key to continue.

使用按键检测的方式取决于您制作游戏循环的方式。如果可接受几十毫秒的抖动,则可以在循环内部添加时间戳检测,而不必太担心。