#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;
}
}
}
So basically my program detects keyboard key (either w,a,s or d which I defined as Ukey,Dkey,Lkey and Rkey). The program is meant to detect the direction by key-press, change the x and y value and maintain it until another key is pressed.
My problem is that when the program run and the default direction (right) is initialized, the while function just stops when I press another key. It will only keep changing the x and y value if I press the key for a few seconds.
What's wrong with my code? It's my first time using kbhit so your answers would be a huge help for me. Thanks.
I think the problem is in the else if(getch()==ukey||getch()==Ukey)
structure, which makes many calls to getch
. If kbhit
has returned true, then the first call to getch
will be non-blocking. However, each additional call will be blocking until a new key is hit.
Solution: Restructure your program so that there is only one call to getch
:
while (true) {
if (kbhit()) {
// A key was pressed. Find out which one.
prev = getch()
}
switch (prev) {
case ukey: y--; break;
case UKey: ...
...
}
}
Furthermore, it would probably be advantageous to specifically detect the two-character response from arrow keys. I don't remember exactly how it works, but the logic would be something like:
if (kbhit()) {
c = getch()
if (c indicates a control character) {
c = getch();
switch c: {
case up arrow: command = up;
...
}
}
}
You may wish to create an enum to store the current "mode" or last command.