После нажатия и начала обработки нажатия клавиши методом _kbhit() и последующим получение обработанной клавиши (_getch()) очищается консоль

Рейтинг: 0Ответов: 1Опубликовано: 30.03.2023

Есть код с циклом выглядит примерно так:

void key_event_handler() { // Обработчик
        if (_kbhit())
        {
            std::cout << _getch() << std::endl;
            if (_getch() == 'd' && x_direction != -1) {
                y_direction = 0;
                x_direction = 1;
            }
            if (_getch() == 'a' && x_direction != 1) {
                y_direction = 0;
                x_direction = -1;
            }
            if (_getch() == 'w' && y_direction != 1) {
                x_direction = 0;
                y_direction = -1;
            }
            if (_getch() == 's' && y_direction != -1) {
                x_direction = 0;
                y_direction = 1;
            }

int main() {
while (true) {
           key_event_handler(); // Вызов обрабочика
           // 1. ...
           // 2. ...
           std::cout << "Тут что то пишется" << std::endl;       
           Sleep(400);
           system("cls");
              }
}


Проблема в том, что при обработке функцией key_event_handler() всё что до обработки было в консоли удаляется и на n-секунд консоль пуста (ну или в ней написан код клавиши которая нажата см. 4 строку). Не подскажете как исправить? Буду благодарен!

Ответы

▲ 3Принят

Проблема заключается в том, что вы используете функцию _getch() для проверки нажатия клавиш в теле цикла if. Вызов _getch() может блокировать выполнение программы до тех пор, пока пользователь не нажмет клавишу. При каждом вызове _getch() программа будет ждать нажатия новой клавиши, и потом считывать ее значение.

Чтобы решить эту проблему, вы можете вызвать _getch() только один раз в начале функции key_event_handler(), а затем сохранить значение в переменной, например:

void key_event_handler() { // Обработчик
    if (_kbhit())
    {
        char key = _getch(); // Сохраняем значение клавиши в переменную

        std::cout << key << std::endl;
        if (key == 'd' && x_direction != -1) {
            y_direction = 0;
            x_direction = 1;
        }
        if (key == 'a' && x_direction != 1) {
            y_direction = 0;
            x_direction = -1;
        }
        if (key == 'w' && y_direction != 1) {
            x_direction = 0;
            y_direction = -1;
        }
        if (key == 's' && y_direction != -1) {
            x_direction = 0;
            y_direction = 1;
        }
    }
}

Таким образом, при каждом вызове функции key_event_handler(), она будет проверять, нажата ли какая-то клавиша, и если да, то выполнит соответствующий блок кода, используя сохраненное значение клавиши. В результате, код, который был написан до вызова key_event_handler(), будет оставаться на консоли, пока функция не обнаружит нажатие клавиши.