Как мне использовать kbhit в C?

#include<stdio.h>
#include<Windows.h>
#include<conio.h>
#define Ukey 87
#define ukey 119
#define Dkey 115
#define dkey 83
#define Lkey 97
#define lkey 65
#define Rkey 100
#define rkey 68

int main(){
    int x=0;
    int y=0;
    int prev=rkey;
    while(true){
        Sleep(50);
        system("cls");
        printf("x : %d\ny : %d",x,y);

        if(!kbhit()){
            if(prev==ukey){
                y--;
            }else if(prev==dkey){
                y++;
            }else if(prev==lkey){
                x--;
            }else if(prev==rkey){
                x++;
            }
        }else if(getch()==ukey||getch()==Ukey){
            y--;
            prev=ukey;
        }else if(getch()==dkey||getch()==Dkey){
            y++;
            prev=dkey;
        }else if(getch()==lkey||getch()==Lkey){
            x--;
            prev=lkey;
        }else if(getch()==rkey||getch()==Rkey){
            x++;
            prev=rkey;
        }
    }
}

Так что в основном моя программа обнаруживает клавиатуру (или w, a, s или d, которые я определил как Ukey,Dkey,Lkey и Rkey). Программа предназначена для определения направления нажатием клавиши, изменения значений x и y и сохранения его до нажатия другой клавиши.

Моя проблема в том, что когда программа запускается и направление по умолчанию (справа) инициализируется, функция while просто останавливается, когда я нажимаю другую клавишу. Изменение значений x и y будет продолжаться только в том случае, если я нажимаю клавишу в течение нескольких секунд.

Что не так с моим кодом? Я впервые использую kbhit, так что ваши ответы будут для меня огромной помощью. Благодарю.

1 ответ

Решение

Я думаю, что проблема в else if(getch()==ukey||getch()==Ukey) структура, которая делает много звонков getch, Если kbhit вернул true, затем первый вызов getch будет неблокирующим Однако каждый дополнительный вызов будет блокироваться до тех пор, пока не будет нажата новая клавиша.

Решение: реструктурируйте вашу программу так, чтобы был только один вызов getch:

while (true) {

  if (kbhit()) {
    // A key was pressed. Find out which one.
    prev = getch()
  }

  switch (prev) {
    case ukey: y--; break;
    case UKey: ...
    ...
  }

}

Кроме того, вероятно, было бы выгодно специально определять двухсимвольный ответ от клавиш со стрелками. Я не помню точно, как это работает, но логика была бы что-то вроде:

if (kbhit()) {
 c = getch()
 if (c indicates a control character) {
   c = getch();
   switch c: {
     case up arrow: command = up;
     ...
   }
 }
}

Вы можете создать перечисление для хранения текущего "режима" или последней команды.

Другие вопросы по тегам