Страницы

Поиск по вопросам

понедельник, 3 декабря 2018 г.

Ввод/вывод в консоли, C++

Здравствуйте.
Решил написать небольшую RPG-игру с псевдографикой в консоли. Для считывания нажатий клавиш использовал функцию GetAsyncKeyState из Windows.h
bool isKeyPressed(int virtualKeyCode) { short keyState = GetAsyncKeyState(virtualKeyCode); return ((keyState & 0x8000) > 0); }
В функции Update проверяю состояние клавиш и изменяю направления движения героя.
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]); } ... }
После этого захотел написать функцию, которая выводила бы на экран вопрос, и при помощи _getch() считывала бы ответ игрока (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; }
Здесь столкнулся с проблемой, что _getch() не останавливает поток и не ждет нажатия клавиши.
При этом если использовать вместо _getch() функцию getchar() или cin.get() на экран консоли выводятся символы ранее нажатых клавиш.


Как я понял,_getch() просто считывает один символ из последних нажатых клавиш (те, которые выводит на экран getchar() или cin.get()) и поэтому не останавливает поток.
То что мне не помогло:
cin.ignore(), cin.clear(), cin.sync(), system("cls"), fflush(stdin)
То что работает, но не так как надо:
Работает, но если до этого когда-то была нажата клавиша Y или N - ответ будет считываться с нее.
do { char input = _getch(); input = tolower(input);
if (input == 'y') { UpdateLog("[Y]"); return true; }
if(input == 'n') { UpdateLog("[N]"); return false; } } while (true); При каждом срабатывании _kbhit() считывать при помощи _getch() символ с потока. Но тогда движение героя и реакция на нажатия клавиш значительно замедляется.
C++, Visual Studio 2015


Ответ

Поскольку потоковое чтение работает в конечном итоге через WinAPI-шные функции и не ожидает, что будет использован прямой доступ к тем же функциям, то оно не дружит с низкоуровневым вводом через GetAsyncKeyState
Поэтому, если уж вы пользуетесь низкоуровневыми функциями, пользуйтесь ими всё время.
Для вашего случая, вам должны помочь FlushConsoleInputBuffer (чтобы сбросить буферизацию уже нажатых к текущему моменту клавиш) и ReadConsoleInput. Вот общая страница документации, на всякий случай.

Комментариев нет:

Отправить комментарий