(Как читать клавиши со стрелками) Чит-код в C-программировании (при вводе с клавиатуры)
Я делаю игру на C, и когда пользователь вводит код Konami (чит-код), программа должна распечатать правильный ответ. (правка № 3) обнаружил, что моя программа не "читает" клавиши со стрелками, когда я ее ввожу, как мне сделать так? пожалуйста. см мой комментарий ниже
Вот мой обновленный код (правка № 2): // попробуйте конами
#include<stdio.h>
#include<string.h>
main() {
int c;
char cheat[] = {24,24,25,25,27,26,27,26,98,97}; //thanks to Vicky for clarifying this
char guess[100];
printf("Enter guess: ");
scanf("%c", &guess);
//just checking if the cheat array is right, and yes it is. I'll remove this later
for ( c = 0; c < 11; c++ ) {
printf("%c", cheat[c]);
}
//comparison of the guess (input) to the cheat code
if (strcmp (cheat, guess) == 0 )
printf("\nYou win!");
else
printf("\nLol!");
}
Теперь, моя проблема, это всегда печатает Lol! хотя я правильно ввел чит-код.,,
примечание: это для моего вводного класса в программировании (мой первый раз в c тоже). Уроки, которые были рассмотрены до сих пор, - это основы, циклы, массивы и строки (функций пока нет, но я понял, что сейчас нет структур и дальнейших действий. Спасибо:)
1 ответ
my question is how do i check it coming from the user
Я слышал, что вы хотите знать, когда пользователь нажимает клавишу со стрелкой? Я должен был сделать это на C++, и это оказалось очень полезным, поэтому, хотя вы используете C, а не C++, я все же поделюсь тем, что помню.
Arrow keys
взять последовательность байтов вместо одного И, как правило, реализуются на аппаратном уровне!
Хотя любая операционная система, которую вы используете, должна иметь поддержку (до свидания, переносимость), термин, который вы должны искать, это key codes
И в windows
они называют их коды виртуальных клавиш
На Windows
Я должен был научиться программировать с win32api.
Я могу легко показать вам 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
#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;
}