I'm building a simple game in C++ and I have a big problem with input buffer, I think. Code below works in a loop and I'm checking if user pressed left or right key in order to move my character. If so, I use switch statement to do appropriate actions. But the problem is that when I'm pressing left key for a while and then change it to right key, my character is still moving left for some time. I think it's because there are characters still in the input buffer when I stop pressing keys. I was trying to fix this problem with cleaning the buffer somehow but everything I found in the Internet doesn't work. For example, I was trying to use
FlushConsoleInputBuffer(stdin);
or
std::cin.clear();
std::cin.sync();
and it all failed because I use it wrong or it simply is not for my purpose. Can you help me with my problem?
MY CODE:
if(GetAsyncKeyState(VK_RIGHT)!= 0 || GetAsyncKeyState(VK_LEFT) != 0){
getch();
int key = getch();
switch(key){
case KEY_LEFT:
//some code
break;
case KEY_RIGHT:
//some code
break;
case KEY_F1:
//some code
break;
default:
break;
}
}
I assuming that you're running this with windows. The problem is that you read the keyboerd status asynchronously but that there might still be some keys in the pipeline.
Reading special keys with getch()
(microsoft recommends using _getch()
) requires reading twice:
When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.
As you skip the first char without checking its validity, buffered input might cause some havoc. You have to discard such unexpected input:
if (...) {
int key;
do key0 = _getch();
while (key != 0 && key != 0xE0); // make sure we read special keys only.
key = _getch();
switch(...) { // don't forget default as key could still be unexpected special key
}
}
But using GetAsyncKeyState()
makes your programme already windows specific. So if your code is still not reactive enough despite this change, you could then as well consider not using getch()
and get a more reactive programme by using directly GetKeyState()
.
if (GetKeyState(VK_RIGHT)!=0) {
// somecode
} else if (...)
...