Hello.

I decided to write a small RPG game with pseudographics in the console. For reading keystrokes, I used the GetAsyncKeyState function from Windows.h

 bool isKeyPressed(int virtualKeyCode) { short keyState = GetAsyncKeyState(virtualKeyCode); return ((keyState & 0x8000) > 0); } 

In the Update function, I check the status of the keys and change the direction of movement of the hero.

  void Update() { if(_kbhit()) { if (isKeyPressed('W')) { unitsArr[heroIndex].changeMoveDirectionTo(0, -1); moveUnitTo(&unitsArr[heroIndex]); } else if (isKeyPressed('S')) { unitsArr[heroIndex].changeMoveDirectionTo(0, 1); moveUnitTo(&unitsArr[heroIndex]); } else if (isKeyPressed('A')) { unitsArr[heroIndex].changeMoveDirectionTo(-1, 0); moveUnitTo(&unitsArr[heroIndex]); } else if (isKeyPressed('D')) { unitsArr[heroIndex].changeMoveDirectionTo(1, 0); moveUnitTo(&unitsArr[heroIndex]); } ... } 

After that, I wanted to write a function that would display a question, and with the help of _getch() I would read the player's answer (y / n)

 bool getAnswerFromLogPanel(const string questionMessage) { UpdateLog(questionMessage + " [Y]/[N]"); const char inputAnswer = tolower(_getch()); if (inputAnswer == 'y') { UpdateLog("[Y]"); return true; } UpdateLog("[N]"); return false; } 

There is a problem here that _getch() does not stop the thread and does not wait for a key to be pressed.

Moreover, if you use the getchar() or _getch() function instead of _getch() the characters of the previously pressed keys are displayed on the console screen.

An example of the display of characters previously pressed keys

An example of the display of characters previously pressed keys

As I understand it, _getch() simply reads one character from the last keystrokes (those that getchar() or cin.get() displays) and therefore does not stop the stream.

What did not help me:

cin.ignore() , cin.clear() , cin.sync() , system("cls") , fflush(stdin) .

What works, but not as it should:

  1. It works, but if before that the Y or N key was once pressed, the answer will be read from it.

     do { char input = _getch(); input = tolower(input); if (input == 'y') { UpdateLog("[Y]"); return true; } if(input == 'n') { UpdateLog("[N]"); return false; } } while (true); 
  2. Each time _kbhit() read a character from the stream using _getch() . But then the movement of the hero and the reaction to keystrokes slows down considerably.

C ++, Visual Studio 2015

  • Low-level input via GetAsyncKeyState is not at all friendly with streaming I / O. Try reading the input through WinAPI functions too. - VladD
  • @VladD Can you tell me which WinAPI functions can be used in this case? - Mad.Mars
  • I think you should ReadConsoleInput and FlushConsoleInputBuffer ( documentation ). - VladD
  • @VladD Thank you. Everything is working. - Mad.Mars
  • Ok, then I'll make out as an answer. - VladD

1 answer 1

Since streaming reading ultimately works through WinAPI functions and does not expect direct access to the same functions to be used, it is not friendly with low-level input via GetAsyncKeyState .

Therefore, if you already use low-level functions, use them all the time.

For your case, you should be assisted by FlushConsoleInputBuffer (to reset the buffering of keys already pressed to the current moment) and ReadConsoleInput . Here is a general documentation page , just in case.