이번에는 KeyManager 클래스에 대해 적어보겠다.
#pragma once
#include "SingletonBase.h"
#define KEY_MAX 256
// " " Manager 라고 하는 것은 대상 객체의 매니저 클래스라는 것을 암묵적으로 의미한다.
class KeyManager:: public SingletonBase <KeyManager>
{
private:
bitset<KEY_MAX> _keyUp;
bitset<KEY_MAX> _keyDown;
public:
HRESULT init(void);
bool isOnceKeyDown(int key); // 키가 한번만 눌렀는지
bool isOnceKeyUp(int key); // 한번 누르고 띄었는지
bool isStayKeyDown(int key); // 키가 계속 눌려있는지
bool isToggleKey(int key);
bitset<KEY_MAX> getKeyUp(void) {return _keyUp;}
bitset<KEY_MAX> getKeyDown(void) {return _keyDown;}
void setKeyDown(int key, bool state) {_keyDown.set(key,state);}
void setKeyUp(int key, bool state) {_keyUp.set(key,state);}
KeyManager();
~KeyManager();
}
#include "Stdafx.h"
#include "KeyManager.h"
HRESULT KeyManager::init(void)
{
// 키값을 전부 눌러있지 않은 상태로 초기화
for(int i = 0; i < KEY_MAX; i++)
{
this->setKeyDown(i,false);
this->setKeyUp(i,false);
}
return S_OK;
}
bool KeyMananger::isOnceKeyDown(int key)
{
// AND 연산 -> & 연산자
// ㄴ 비트 단위로 AND 연산을 수행한다.
// 둘다 1일때만 결과가 1이고 아니라면 0 이다.
if(GetAsyncKeyState(key) & 0x8000) // -> 지금 키가 눌림
{
if(!this->getKeyDown()[key]) // 이전에 키가 눌러져 있지 않은 상태에서
{
this->setKeyDown(key,true); // 키가 눌러져 있다면 true
return true;
}
}
else this->setKeyDown(key,false); // 키가 눌러져 있지 않다면 false
return false;
}
bool KeyManager::isOnceKeyUp(int key)
{
if(GetAsyncKeyState(key) & 0x8000) // -> 지금 키가 눌림
{
this->setKeyUp(key,true);
}else
{
if(this->getKeyUp()[key])
{
this->setKeyUp(key,false); // 키가 눌러져 있지 않다면 true
return true;
}
}
return false;
}
bool KeyManager::isStayKeyDown(int key)
{
if (GetAsyncKeyState(key) & 0x8000) return true; // -> 지금 키가 눌리면 true
return false;
}
bool KeyManager::isToggleKey(int key)
{
if (GetKeyState(key) & 0x0001) return true; // -> 이전과 지금 사이에 키가 눌림
return false;
}
KeyManager::KeyManager()
{
}
KeyManager::~KeyManager()
{
}
▶ GetAsyncKeyState
어떤 키가 입력된건지 체크 or 프로그램에서 키를 입력받고 싶을때 사용하는 API 공용함수
메세지 큐에 있는 키의 정보를 확인(가져)온다.
키가 눌린 시점을 체크하기 위해 &(AND) 연산을 사용한다.
GetAsyncKeyState의 반환 값
0(0x0000) : 이전에 누른 적이 없고 호출 시점에서 안눌린 상태
0x8000 : 이전에 누른 적이 없고 호출 시점에서만 눌린 상태
0x8001 : 이전에 누른 적이 있고 호출 시점에서만 눌린 상태
1(0x0001) : 이전에 누른 적이 있고 호출 시점에서 안눌린 상태