my question is how do i check it coming from the user
我听说您想知道用户何时按下箭头键?我必须在 C++ 中执行此操作,结果证明这是一次非常有启发性的体验,因此尽管您使用的是 C 而不是 C++,但我仍然会分享我记得的内容。
Arrow keys 采用字节序列而不是一个 AND 通常在硬件级别实现!
尽管您使用的任何操作系统都应该有支持(再见可移植性),但您需要寻找的术语是key codes,在windows 他们称它们为Virtual-Key Codes
在Windows我已经学会了用win32api编程。
我可以轻松地向您展示 Windows 的 key codes(我将从该链接粘贴它们)但它们对您没有好处,除非您想提交 Windows 事件驱动类型程序(也许您已经是?) ,这些代码是从您程序中的key 事件中获取的,而不是ascii-codes,我会尽可能假设特定于windows。
VK_LEFT
0x25
LEFT ARROW key
VK_UP
0x26
UP ARROW key
VK_RIGHT
0x27
RIGHT ARROW key
VK_DOWN
0x28
在 linux 中,我仍然需要处理事件,这次使用 X11,哦,我在 X11 上的乐趣!这里的键码称为XK_[key],即XK_left。
这些键码在标题<X11/keysymdef.h> - Xlib programming manual中定义
见header online
#define XK_Left 0xff51 /* Move left, left arrow */
#define XK_Up 0xff52 /* Move up, up arrow */
#define XK_Right 0xff53 /* Move right, right arrow */
#define XK_Down 0xff54 /* Move down, down arrow */
希望这可以让您走上正确的道路,每当我需要 arrow keys 时,我现在只需使用 wasd。
编辑:这是 Windows 版本,我将它从我制作的 C++ 游戏浓缩到这个 C 程序中,它有很多代码,任何看起来不应该存在的东西可能都不应该存在,但它可以编译并读取箭头键,因此您需要的一切至少在此源中。
Windows;
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <Tchar.h>
//directional keys
#define key_left 0x25
#define key_up 0x26
#define key_right 0x27
#define key_down 0x28
// to quit
#define key_escape 0x1B
char checkType(INPUT_RECORD *buffer, int i);
int checkKey(INPUT_RECORD *buffer, int i);
void outputString(const char *str, SHORT col, SHORT row);
void outputChar(char ch, SHORT col, SHORT row);
void clearScreen(void);
CHAR_INFO *p_consoleBuffer;
HANDLE whnd; // handle to write console
HANDLE rhnd; // handle to read console
SMALL_RECT winSize;
COORD buffSize;
SHORT consoleHeight = 25;
SHORT consoleWidth = 60;
DWORD Events = 0; // Event count
DWORD EventsRead = 0; // Events read from console
int _tmain(int argc, _TCHAR* argv[]){
// set up handles for read/writing:
whnd = GetStdHandle(STD_OUTPUT_HANDLE);
rhnd = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleTitle(TEXT("DEMO WIN PROG"));
SMALL_RECT winLen = {0,0,((SHORT)consoleWidth-1),((SHORT)consoleHeight-1)};
COORD bLen = {consoleWidth,consoleHeight}; // width / height
winSize = winLen;
// set console size
SetConsoleWindowInfo(whnd, TRUE, &winSize);
// set the buffer size coords
SetConsoleScreenBufferSize(whnd, buffSize);
CHAR_INFO consoleBuffer[consoleHeight*consoleWidth];
p_consoleBuffer = consoleBuffer;
CONSOLE_CURSOR_INFO cci;
cci.dwSize = 1;
cci.bVisible = FALSE;
SetConsoleCursorInfo(whnd, &cci);
clearScreen();
int Running = 1;
char type = 0;
while(Running) {
//game loop
GetNumberOfConsoleInputEvents(rhnd, &Events);
if(Events != 0){ // something happened
// create buffer the size of how many Events & store
INPUT_RECORD eventBuffer[Events];
// fills buffer with events and save count in EventsRead
ReadConsoleInput(rhnd, eventBuffer, Events, &EventsRead);
DWORD i;
for(i = 0; i<EventsRead; ++i){
type = checkType(eventBuffer,i);
if(type == 'k'){ // event type was key
int key = checkKey(eventBuffer, i);
int arrow_key_pressed = FALSE;
switch (key){
case key_up:
case key_down:
case key_left:
case key_right:
// IF ANY ARROW KEY WAS PRESSED, EXECUTION WILL "COLLAPSE" TO HERE
arrow_key_pressed = TRUE;
break;
case key_escape:
// escape was pressed
Running = 0;
break;
default:
// no case was pressed
break;
}
clearScreen();
if(arrow_key_pressed){
const char *str = "Arrow key was pressed";
outputString(str, 20, 12); // roughly centre
}else {
const char *str = "Arrow key was not pressed";
outputString(str, 20, 12);
}
}else if(type == 'm'){
// MOUSE CLICK, I'M NOT COVERING SORRY.
}
}
}
}
return 0;
}
char checkType(INPUT_RECORD *buffer, int i){
if(buffer[i].EventType == MOUSE_EVENT){
return ('m');
}else if(buffer[i].EventType == KEY_EVENT){
return ('k');
}else return (0);
}
int checkKey(INPUT_RECORD *buffer, int i){
return (buffer[i].Event.KeyEvent.wVirtualKeyCode);
}
void outputString(const char *str, SHORT col, SHORT row){
SHORT fs_len = strlen(str);
int i;
for(i = 0; i<fs_len; ++i){
outputChar(str[i], col++, row);
}
}
void outputChar(char ch, SHORT col, SHORT row){
p_consoleBuffer[row*consoleWidth+col].Char.AsciiChar = ch;
p_consoleBuffer[row*consoleWidth+col].Attributes = 240;
SHORT CH = consoleHeight, CW = consoleWidth;
COORD charBufSize = {CW,CH};
COORD charPos = {0,0};
SMALL_RECT writeArea = {0,0,CW,CH};
WriteConsoleOutputA(whnd,p_consoleBuffer,charBufSize,charPos,&writeArea);
}
void clearScreen(void){
int i;
for(i = 0; i<(consoleHeight*consoleWidth); ++i){
//fill it with white-backgrounded spaces
p_consoleBuffer[i].Char.AsciiChar = ' ';
p_consoleBuffer[i].Attributes =
BACKGROUND_BLUE |
BACKGROUND_GREEN |
BACKGROUND_RED |
BACKGROUND_INTENSITY;
}
// clear screen
SHORT CH = consoleHeight, CW = consoleWidth;
COORD charBufSize = {CW,CH};
COORD charPos = {0,0};
SMALL_RECT writeArea = {0,0,CW,CH};
WriteConsoleOutputA(whnd,p_consoleBuffer,charBufSize,charPos,&writeArea);
}
/* Remember i did this in c++, i made a class with these ints
to represent the virtual key codes, you can define them how you
want like i did or use windows actual definitions.
//special keys
key_escape = 0x1B;
key_space = 0x20;
key_home = 0x24;
key_end = 0x23;
key_pgUp = 0x21;
key_pgDown = 0x22;
key_caps = 0x13;
key_shift = 0x10;
key_ctrl = 0x11;
key_backspace = 0x08;
key_tab = 0x09;
key_enter = 0x0D;
key_alt = 0x12;
key_delete = 0x2E;
//directional keys
key_left = 0x25;
key_up = 0x26;
key_right = 0x27;
key_down = 0x28;
//number keys
key_0 = 0x30;
key_1 = 0x31;
key_2 = 0x32;
key_3 = 0x33;
key_4 = 0x34;
key_5 = 0x35;
key_6 = 0x36;
key_7 = 0x37;
key_8 = 0x38;
key_9 = 0x39;
// alphabet keys
key_a = 0x41;
key_b = 0x42;
key_c = 0x43;
key_d = 0x44;
key_e = 0x45;
key_f = 0x46;
key_g = 0x47;
key_h = 0x48;
key_i = 0x49;
key_j = 0x4A;
key_k = 0x4B;
key_l = 0x4C;
key_m = 0x4D;
key_n = 0x4E;
key_o = 0x4F;
key_p = 0x50;
key_q = 0x51;
key_r = 0x52;
key_s = 0x53;
key_t = 0x54;
key_u = 0x55;
key_v = 0x56;
key_w = 0x57;
key_x = 0x58;
key_y = 0x59;
key_z = 0x5A;
*/
LINUX: (X11) 这是我使用的示例程序,实际上当我第一次开始编程时,我想自己做这个,我不记得它来自哪里或是谁写的,所以我不能相信他们不幸的是,但这是来源;
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
/*Linux users will need to add -ldl to the Makefile to compile
*this example.
*/
Display *dis;
Window win;
XEvent report;
GC green_gc;
XColor green_col;
Colormap colormap;
/*
Try changing the green[] = below to a different color.
The color can also be from /usr/X11R6/lib/X11/rgb.txt, such as RoyalBlue4.
A # (number sign) is only needed when using hexadecimal colors.
*/
char green[] = "#00FF00";
int main() {
dis = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0, BlackPixel (dis, 0), BlackPixel(dis, 0));
XMapWindow(dis, win);
colormap = DefaultColormap(dis, 0);
green_gc = XCreateGC(dis, win, 0, 0);
XParseColor(dis, colormap, green, &green_col);
XAllocColor(dis, colormap, &green_col);
XSetForeground(dis, green_gc, green_col.pixel);
XSelectInput(dis, win, ExposureMask | KeyPressMask | ButtonPressMask);
XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497);
XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398);
XFlush(dis);
while (1) {
XNextEvent(dis, &report);
switch (report.type) {
case Expose:
fprintf(stdout, "I have been exposed.\n");
XDrawRectangle(dis, win, green_gc, 1, 1, 497, 497);
XDrawRectangle(dis, win, green_gc, 50, 50, 398, 398);
XFlush(dis);
break;
case KeyPress:
/*Close the program if q is pressed.*/
if (XLookupKeysym(&report.xkey, 0) == XK_q) {
exit(0);
}
break;
}
}
return 0;
}