(2022) 공부 (Study)/게임 개발 (Development)

[Win32API] GetAsyncKeyState() 와 키 입력 받기 (1)

수낭 2022. 4. 13. 17:53

이번에는 가상 키 값과 키보드 입력을 받는 방법에 대해서 알아보겠습니다.

_getch() 함수는 가장 마지막에 입력한 값만 받을 수 있으므로, 대각선 이동을 구현할 수 없습니다.
switch(wParam) / case WM_KEYDOWN을 통한 가상 키 값에 따른 분기로 입력받는 방식은 비동기 구현이 어렵습니다.

CKeyMgr와 같이 별도의 클래스로 분리하여 비동기로 구현하기 위해서는 새로운 방법이 필요합니다.

 

 

이번 포스팅에 해당되는 코드는 아래 git에서 확인 가능하다.

https://github.com/nr97819/Win32_ASTR_Lecture/tree/Lecture-12

 

GitHub - nr97819/Win32_ASTR_Lecture: Win32_ASTR_Lec

Win32_ASTR_Lec. Contribute to nr97819/Win32_ASTR_Lecture development by creating an account on GitHub.

github.com

 

 

그래서 이번에 사용할 함수는 GetAsyncKeyState() 라는 함수이고,
비동기 값 / 상태를 입력 받는 것이 가능한 함수입니다.

WINUSERAPI
SHORT
WINAPI
GetAsyncKeyState(
    _In_ int vKey);

반환 값이 SHORT이며, 눌린 Key 값은 물론 State를 기록하는 특징이 있습니다.

 

class CKeyMgr
{
	SINGLE(CKeyMgr);
private:
	// vector 내의 index가 곧, enum class KEY의 값이다.
	vector<tKeyInfo> m_vecKey;

public:
	void Init();
	void Update();
	KEY_STATE GetKeyState(KEY _eKey) { return m_vecKey[(int)_eKey].estate; }
};

Key Manager 역시, SINGLETON으로 구현하게 됩니다.
(매니저는 대부분 특성상 SINGLETON 디자인 패턴과 잘 어울린다.)

 

GetKeyState() 라는 함수도 존재하는데, GetAsyncKeyState() 함수와의 차이점은 함수명에서 알 수 있듯이,
GetAsyncKeyState() 함수는 비동기로 처리합니다.

즉, 호출된 시점에서 Key State(상태)를 조사하여, Message Queue를 거치지 않고 바로 return 해주므로,
키 입력을 지연 없이 바로 처리해 줄 수 있습니다.
(GetKeyState() 함수가 호출 된 그 시점에, 해당 Key가 눌려있는지 비교하게 됩니다.)

반대로 GetKeyState() 함수는 호출된 시점에서 메시지 큐를 거치게 되며, 메시지 발생 후의 state를 return 하게 되며,
키보드 Message 처리 루틴 내에서만 사용할 수 있습니다.
(즉, Message Queue를 거쳐서 작동하므로, Game과 같은 지연 없는 Key 입력 처리에 부적합합니다.)

 

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

각 비트가 갖는 의미는 위 표와 같습니다. (MSDN에서 찾아볼 수 있습니다.)

 

if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
	vPos.x -= 300.f * CTimeMgr::GetInst()->GetfDT();
}

단순히 해당 Key 값이 눌렸는지만 확인하기 위해서는,
0x8000AND 비트 연산해주면 됩니다.
(위 함수는 매 frame 마다 호출되도록 작성되어, 키 입력을 수시로 체크하도록 구현되었습니다.)

 

vPos.x += 300.f * CTimeMgr::GetInst()->GetfDT();

미리 정해둔 속도 상수 값 (300.f)를 기준으로 넣어두고, 전에 만들어둔 Time ManagerDelta Time 만큼을
곱하는 형식으로 되어있습니다.

CCore::update( ) 함수는 매 프레임마다 호출되므로, 컴퓨터의 성능에 따른 프레임의 높/낮음 정도와는 관계없이
물체의 이동량을 동일하게 하기 위해서는, "거리 = 속력 * 시간" 공식을 통해서
모든 PC들이 동일한 이동 거리 값을 갖도록 Delta Time을 곱해주는 것입니다.

 

 

가상 키 코드(Winuser.h) - Win32 apps

다음 표에서는 시스템에서 사용 하는 가상 키 코드에 해당 하는 기호화 된 상수 이름, 16 진수 값, 마우스 또는 키보드를 보여 줍니다. 코드는 숫자 순서로 나열 됩니다.

docs.microsoft.com

가상 키 코드는 MSDN에서 확인할 수 있습니다.
https://docs.microsoft.com/ko-kr/windows/win32/inputdev/virtual-key-codes

 

다음 포스팅에서는 Key 입력에 대한 State(상태) 값을 이용하는 방법을 알아보겠습니다.

https://soonang2.tistory.com/30

 

[Win32API] GetAsyncKeyState() 와 키 입력 받기 (2)

https://soonang2.tistory.com/28 [Win32API] GetAsyncKeyState() 와 키 입력 받기 (1) 이번에는 가상 키 값과 키보드 입력을 받는 방법에 대해서 알아보겠습니다. _getch() 함수는 가장 마지막에 입력한 값만 받..

soonang2.tistory.com