(Как читать клавиши со стрелками) Чит-код в 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;
}
Другие вопросы по тегам