KeyManager
2022. 12. 24. 12:06ㆍ개인공부/Win32API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
struct tKeyInfo
{
// KEY ekey -> 본인의 인덱스가 곧 키이므로 저장할 필요가 없다.
KEY_STATE eState; // 키의 상태값
bool bPrevPush; // 이전 프레임에서 눌렸는지 여부
};
class CKeyMgr
{
SINGLE(CKeyMgr);
private:
vector<tKeyInfo> m_vecKey; // 벡터와 이넘클래스, 구조체 이용해서 공간 만드는 방법 다시 숙지하자
public:
void init();
void update();
public:
KEY_STATE GetKeyState(KEY _eKey)
{
return m_vecKey[(int)_eKey].eState;
}
};
|
cs |
키입력의 경우에는 1 프레임 단위로 갱신이 되는데 4가지의 상태를 가지고 있다. 이런식으로 구분을 해야지 어떤 프레임에서의 키보드 입력에 대해서 관리하기가 수월해진다
1
2
3
4
5
6
7
8
|
enum class KEY_STATE
{
NONE, // 눌리지 않음, 이전에도 눌리지 않은 상태
TAP, // 막 누른 시점
HOLD, // 누르고 있는
AWAY, // 막 뗸 시점
};
|
cs |
여기서 vector 를 이용해서 tKeyInfo 배열을 만드는데 전부터 벡터를 클래스안에서 정의하는 방법에 대해서 고민했었는데 어떤 방식으로 사용하는지 알 수 있었다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
int g_arrVK[(int)KEY::LAST] =
{
VK_LEFT,//LEFT,
VK_RIGHT,//RIGHT,
VK_UP,//UP,
VK_DOWN,//DOWN,
'Q',
'W',
'E',
'R',
'T',
'Y',
'U',
'I',
'O',
'P',
'A',
'S',
'D',
'F',
'G',
'Z',
'X',
'C',
'V',
'B',
VK_MENU,//ALT,
VK_CONTROL,//CTRL,
VK_LSHIFT,//LSHIFT,
VK_SPACE,//SPACE,
VK_RETURN,//ENTER,
VK_ESCAPE,//ESC,
//LAST,
};
|
cs |
이런 방식으로 키보드 입력값은 제각각의 값을 가지기 때문에 미리 입력해둔 enum class 와 순서를 맞춰서 한개씩 조건을 만들지 않아도 되는 방법이 있었다. 다음번에 게임을 만들때는 이러식으로 만들자고 생각했다.
1
2
3
4
5
6
7
8
9
|
void CKeyMgr::init()
{
for (int i = 0; i < (int)KEY::LAST; ++i)
{
m_vecKey.push_back(tKeyInfo{ KEY_STATE::NONE, false });
}
}
|
cs |
키매니저는 초기화할때 vector의 push_back 함수를 이용해서 아무것도 눌리지 않고 이전프레임도 눌리지 않은상태 값을 대입한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
void CKeyMgr::update()
{
// 윈도우 포커싱 알아내기
//HWND hMainWnd = CCore::GetInst()->GetMainHwnd(); //나의 윈도우
HWND hWnd = GetFocus(); // 현재 포커싱중인 윈도우
// 윈도우가 포커싱 중일 떄 키 이벤트 동자
if (nullptr != hWnd)
{
for (int i = 0; i < (int)KEY::LAST; ++i)
{
// 키를 눌렀다
if (GetAsyncKeyState(g_arrVK[i]) & 0x8000)
{
if (m_vecKey[i].bPrevPush)
{
// 이전에도 눌렀다.
m_vecKey[i].eState = KEY_STATE::HOLD;
}
else
{
// 이전에도 눌려있지 않았다.
m_vecKey[i].eState = KEY_STATE::TAP;
}
m_vecKey[i].bPrevPush = true;
}
// 키가 안눌려 있다.
else
{
if (m_vecKey[i].bPrevPush)
{
// 이전에도 눌려 있었다.
m_vecKey[i].eState = KEY_STATE::AWAY;
}
else
{
// 이전에도 안눌려있었다.
m_vecKey[i].eState = KEY_STATE::NONE;
}
m_vecKey[i].bPrevPush = false;
}
}
}
else
{
for (int i = 0; i < (int)KEY::LAST; ++i)
{
m_vecKey[i].bPrevPush = false;
if (KEY_STATE::TAP == m_vecKey[i].eState || KEY_STATE::HOLD == m_vecKey[i].eState)
{
m_vecKey[i].eState = KEY_STATE::AWAY;
}
else if (KEY_STATE::AWAY == m_vecKey[i].eState)
{
m_vecKey[i].eState = KEY_STATE::NONE;
}
}
}
}
|
cs |
이후에는 현재 윈도우가 포커싱여부를 확인하는 함수를 이용해서 조건을 작성하고 조건에 따라서 상태값을 만들어주면되는데 else이후에 포커싱의 해제된 이후에도 현재상태의 따라서 값을 처리해주는 방식을 사용해서 오류를 방지해주는 코드를 강의를 통해서 들었는데 이런 예외처리를 확실하게 하 는 것이 중요하다.
다음 정리는 Scene 에대해서 정리 예정이다.
'개인공부 > Win32API' 카테고리의 다른 글
PathMgr (0) | 2022.12.26 |
---|---|
Object (0) | 2022.12.25 |
TimeManager (0) | 2022.12.23 |
공부 정리 (0) | 2022.12.21 |
PeekMessage (0) | 2022.12.19 |