简体   繁体   中英

How do I read keyboard input in C++?

Here is my attempt of moving a simple triangle drawn with DirectX 11 in C++:

int DrawAndMovePlayer(Renderer renderer)
{
    Triangle triangle1(renderer);
    float p1, p2, p3, p4, p5, p6;
    float x, y;
    x = 0.0f;
    y = 0.0f;

    if (GetAsyncKeyState(0x58))
    {
        x = 1.0f;
    }

    // Top
    p1 = x + 0.0f;
    p2 = y + 0.05f;

    // Bottom Right
    p3 = x + 0.05f;
    p4 = y - 0.05f;

    // Top
    p5 = x - 0.05f;
    p6 = y - 0.05f;

    // Triangle triangle2(renderer);
    triangle1.draw(renderer, p1, p2, p3, p4, p5, p6);

    //triangle2.draw(renderer, -0.5f);
    return 0;
}

I have tried the getch() function and the GetAsyncKeyState() function. However, the triangle never changes its position. The triangle is drawn around a center point ( x , y ).

I find the official documentation of GetAsyncKeyState a bit confusing. I think that this forum post gives a better explanation on how GetAsyncKeyState works:

GetAsyncKeyState returns a 16-bit signed value. The high bit is set when the current real-time state of the key indicates that it is being held down.

The low bit is set when the key has transitioned from a released to a pressed state (like when the key is first pressed). Though the MSDN documentation indicates this is not reliable.

The value of all other bits should be assumed to be "undefined" and you should discard them. I would not recommend assuming they are 0 because they might not be a in a future version.

That said... you should NOT look for absolute return values. IE: checking for -32767 is wrong. Instead, you should mask out the bit you're interested in:

 if(GetAsyncKeyState(x) & 0x8000) { // high bit is set. Key is currently held down. } if(GetAsyncKeyState(x) & 0x0001) { // low bit is set. Key just transitioned from released to pressed. }

So, this recommendation matches that one given by @MikeCAT in the comments: You should use GetAsyncKeyState(0x58) & 0x8000 to see if the X key is pressed.

Here you go, It took me a while to figure this one out on Microsoft Visual Studio 2015: but here it is:

MSG message;
message.message = WM_NULL;
while (message.message != WM_QUIT) {
    while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { // Make a class file for this or something
                                                           // so when it's HUGE it won't be obtrusive...
                                                           // I mean REALLY.
        if (message.message == WM_KEYDOWN) {
            if (GetAsyncKeyState(0x51) == 0x0001); {
                OutputDebugString("key pressed \n");
                pressed = true;
            }
        }
        if (message.message == WM_KEYUP) {
            if (GetAsyncKeyState(0x51) != 0x0000); {
                OutputDebugString("key unpressed");
                pressed = false;
            }
        }
        DispatchMessage(&message);
    }`

The key in question here being 'q' or virtual key code 0x51. And this is all after you create a window, and set things up. If you want the complete code, please comment, or contact me.

Some more working current code, Visual Studio 2017:

INT_PTR CALLBACK myModalessWindow(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
        case WM_CHAR: // Case sensitive
            if ((char)wParam == 'A')
                Beep(2000, 250);
            if ((char)wParam == 'b')
                Beep(2000, 250);
        break;

        case WM_KEYDOWN:
            {
                if (GetKeyState('A') & 0x8000 /* Check if high-order bit is set (1 << 15)*/)
                    Beep(2000, 250);

                if (wParam == 'S') // Not case sensitive.
                    Beep(2000, 250);
            }
        break;
    }
}

You could allegro or sfml libraries but for a quick solution:

#include iostream
using namespace std;

int main() {
    char input;
    cin >> input;

    if (input == f) 
    {
        //do something
    }

    return 0;
}

Or if you need to more key options, you could always replace the if statement with a switch statement. If you want something that runs through the entire program (for example if anytime during the program, someone presses something something will happen, you need to learn about multithreading- check out sfml).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM