[C언어/C++] 캐릭터 움직이기 (GetAsyncKeyState 함수 사용법)

다중키 입력이 가능한 GetAsyncKeyState

C언어 / C++에서 입력키의 정보를 알아오기 위해 _getch()를 종종 사용하고는 합니다. 하지만 _getch() 함수는 마지막에 누른 키 하나만을 입력받습니다. 그렇기에 좌,우,상,하 키를 동시에 입력받지 못하여 "대각선 이동" 모션을 할수가 없습니다. 게임을 개발하기 위해서는 _getch()함수보다는 GetAsyncKeyState()함수를 사용하도록 합시다. GetAsyncKeyState()함수는 입력을 멀티로 받을 수 있습니다. →키와 ↑키를 동시에 누른다면 오른쪽 위의 대각선 방향으로 이동을 할 수 있게됩니다.

 

 GetAsyncKeyState 사용법 

SHORT GetAsyncKeyState(int vKey)

함수의 형태는 위와 같습니다. 인자값으로는 키보드의 키 (ex : VK_LEFT) 같은 키값이 오며 리턴값으로는 Short를 반환합니다. 정확히는 Short보다는 비트값이라고 보는것이 맞습니다.

 

GetAsyncKeyState의 반환값

반환값 설명
0(0x0000) 이전에 누른 적이 없고 호출 시점에서 안눌린 상태
0x8000  이전에 누른 적이 없고 호출 시점에서 눌린 상태
0x8001  이전에 누른 적이 있고 호출 시점에서 눌린 상태
1(0x0001) 이전에 누른 적이 있고 호출 시점에서 안눌린 상태

GetAsyncKeyState는 키의 상태에 따라 위와 같이 반환값이 비트형태로 리턴됩니다. 그렇기에 이 반환값을 활용하기 위해서는 아래와 같이 비트연산자를 활용해야합니다.

if(GetAsyncKeyState(VK_LEFT) & 0x8000) -> 지금 키가 눌림
if(GetAsyncKeyState(VK_LEFT) & 0x0001) -> 이전과 지금 사이에 키가 눌림 
if(GetAsyncKeyState(VK_LEFT)) -> 둘다 가능

게임 개발을 위해서라면  if(GetAsyncKeyState(VK_LEFT)) 이 형태로 사용하는것을 가장 추천드립니다.

 

GetAsyncKeyState와 GetKeyState의 차이점

GetAsyncKeyState()함수는 비동기로 처리합니다. 즉, 호출된 시점에서 키 상태를 조사하여, 메시지 큐를 거치지 않고 바로 리턴해주므로 키 입력을 바로 처리해 줄 수 있습니다. 반대로 GetKeyState()함수는 호출된 시점에서 메시지 큐를 거치게 되며, 메시지 발생 후의 상태를 리턴하게 되며 키보드 메시지 처리 루틴내에서 사용할 수 있습니다.

 

대부분의 게임은 현재 눌린키값이 무엇인지가 중요하고 이전에 눌린 키의 값은 중요하지 않습니다. GetKeyState()함수를 사용할 시 메시지 큐에 처리되지 않은 키값이 남아있다면 키가 눌렸다고 인식이 되므로 GetAsyncKeyState함수를 사용하는것이 불필요한 오류를 예방할 수 있습니다.

 

GetAsyncKeyState 함수를 활용하여 캐릭터 이동시키기

#include<stdio.h>
#include<windows.h>

void gotoxy(int x, int y) {
    COORD Pos = { x - 1, y - 1 };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void main() {
    int x = 1;
    int y = 1;
    gotoxy(x, y);
    while (1) {
        if (GetAsyncKeyState(VK_LEFT) & 0x8000) { //왼쪽
            x--;
        }
        if (GetAsyncKeyState(VK_RIGHT) & 0x8000) { //오른쪽
            x++;
        }
        if (GetAsyncKeyState(VK_UP) & 0x8000) { //위
            y--;
        }
        if (GetAsyncKeyState(VK_DOWN) & 0x8000) { //아래
            y++;
        }
        
        system("cls");
        gotoxy(x, y);
        printf("♥");
    }
}

콘솔 캐릭터 움직이기

간단하게 위, 아래, 오른쪽, 왼쪽의 키값을 받아 좌표를 움직이는 예제를 만들어 보았습니다. 캐릭터를 이동시키고 싶다면 입력키별로 좌표값을 조정하여 캐릭터를 이동시키시면 됩니다.

 

가상 키 코드

가상키 코드 설명
0x01 VK_LBUTTON 마우스 왼쪽 버튼
0x02 VK_RBUTTON 마우스 오른쪽 버튼
0x03 VK_CANCEL Ctrl + Break
0x04 VK_MBUTTON 마우스 가운데 버튼
0x05 VK_XBUTTON1 X1 마우스 버튼
0x06 VK_XBUTTON2 X2 마우스 버튼
0x07 - <정의되지 않음>
0x08 VK_BACK Backspace
0x09 VK_TAB Tab
0x0A-0x0B - <예약됨>
0x0C VK_CLEAR Clear 키
0x0D VK_RETURN Enter
0x0E-0x0F - <정의되지 않음>
0x10 VK_SHIFT Shift
0x11 VK_CONTROL Ctrl
0x12 VK_MENU Alt
0x13 VK_PAUSE Pause
0x14 VK_CAPITAL Caps Lock
0x15 VK_KANA / VK_HANGUL IME 가나 모드 / 한글 모드
0x16 - <정의되지 않음>
0x17 VK_JUNJA IME 전자모드
0x18 VK_FINAL IME 최종모드
0x19 VK_HANJA / VK_KANJI IME 한자모드
0x1A - <정의되지 않음>
0x1B VK_ESCAPE Esc
0x1C VK_CONVERT IME 변환
0x1D VK_NONCONVERT IME 변환 안함
0x1E VK_ACCEPT IME 승인
0x1F VK_MODECHANGE IME 모드 변경 요청
0x20 VK_SPACE Space Bar
0x21 VK_PRIOR Page Up
0x22 VK_NEXT Page Down
0x23 VK_END End
0x24 VK_HOME Home
0x25 VK_LEFT
0x26 VK_UP
0x27 VK_RIGHT
0x28 VK_DOWN
0x29 VK_SELECT Select
0x2A VK_PRINT Print Screen
0x2B VK_EXECUTE Execute
0x2C VK_SNAPSHOT Print Screen
0x2D VK_INSERT Insert
0x2E VK_DELETE Delete
0x2F VK_HELP Help
0x30 - 0
0x31 - 1
0x32 - 2
0x33 - 3
0x34 - 4
0x35 - 5
0x36 - 6
0x37 - 7
0x38 - 8
0x39 - 9
0X3A-0X40 - <정의되지 않음>
0x41 - A
0x42 - B
0x43 - C
0x44 - D
0x45 - E
0x46 - F
0x47 - G
0x48 - H
0x49 - I
0x4A - J
0x4B - K
0x4C - L
0x4D - M
0x4E - N
0x4F - O
0x50 - P
0x51 - Q
0x52 - R
0x53 - S
0x54 - T
0x55 - U
0x56 - V
0x57 - W
0x58 - X
0x59 - Y
0x5A - Z
0x5B VK_LWIN 왼쪽 윈도우 키
0x5C VK_RWIN 오른쪽 윈도우 키
0x5D VK_APPS 어플리케이션 키
0x5E - <예약됨>
0x5F VK_SLEEP Computer Sleep키
0x60 VK_NUMPAD0 숫자 키패드0
0x61 VK_NUMPAD1 숫자 키패드1
0x62 VK_NUMPAD2 숫자 키패드2
0x63 VK_NUMPAD3 숫자 키패드3
0x64 VK_NUMPAD4 숫자 키패드4
0x65 VK_NUMPAD5 숫자 키패드5
0x66 VK_NUMPAD6 숫자 키패드6
0x67 VK_NUMPAD7 숫자 키패드7
0x68 VK_NUMPAD8 숫자 키패드8
0x69 VK_NUMPAD9 숫자 키패드9
0x6A VK_MULTPLY 숫자 키패드*
0x6B VK_ADD 숫자 키패드+
0x6C VK_SEPARATOR Separator키
0x6D VK_SUBTRACT 숫자 키패드-
0x6E VK_DECIMAL 숫자 키패드.
0x6F VK_DIVDE 숫자 키패드/
0x70 VK_F1 F1
0x71 VK_F2 F2
0x72 VK_F3 F3
0x73 VK_F4 F4
0x74 VK_F5 F5
0x75 VK_F6 F6
0x76 VK_F7 F7
0x77 VK_F8 F8
0x78 VK_F9 F9
0x79 VK_F10 F10
0x7A VK_F11 F11
0x7B VK_F12 F12
0x7C VK_F13 F13
0x7D VK_F14 F14
0x7E VK_F15 F15
0x7F VK_F16 F16
0x80 VK_F17 F17
0x81 VK_F18 F18
0x82 VK_F19 F19
0x83 VK_F20 F20
0x84 VK_F21 F21
0x85 VK_F22 F22
0x86 VK_F23 F23
0x87 VK_F24 F24
0x88-0x8F - NumLock
0x90 VK_NUMLOCK ScrollLock
0x91 VK_SCROLL OEM키
0x92-0x96 - <할당되지 않음>
0xA0 VK_LSHIFT 왼쪽 Shift
0xA1 VK_RSHIFT 오른쪽 Shift
0xA2 VK_LCONTROL 왼쪽 Ctrl
0xA3 VK_RCONTROL 오른쪽 Ctrl
0xA4 VK_LMENU 왼쪽 Alt
0xA5 VK_RMENU 오른쪽 Alt
0xA6-0xFE - <이하생략>



댓글(4)

Designed by JB FACTORY