Страницы

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

пятница, 27 декабря 2019 г.

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

#cpp #visual_studio_2015 #консоль #вывод #ввод


Здравствуйте.

Решил написать небольшую 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
    


Ответы

Ответ 1



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

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

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