https://soonang2.tistory.com/30
※ 이전 포스팅과 이어지는 내용이므로, 먼저 읽고 오시는 것을 추천드립니다. ※
※ 이번 포스팅의 Source Code는 아래 git 링크에서 볼 수 있습니다. ※
https://github.com/nr97819/Win32_ASTR_Lecture/tree/Lecture-14
이번에는, 해당 Window 창이 최소화 되어있거나, focusing 되어있지 않은 상태라면,
Key 입력을 받지 않도록 설정해보도록 하자.
(게임 이외의 창을 띄웠는데도 게임 캐릭터가 움직이면 말이 안되므로)
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_DOWN:
// logic ...
break;
}
}
break;
우리만의 자체 Key 입력 매니저를 만들기 전까지는, 위와 같은 형태의
Window 자체 기능들을 이용했었고, 이러한 것들은 우리가 기능을 수정할 수 없었다.
하지만 우리는 Key Manager를 자체적으로 만들어서 사용하고 있으므로,
해당 Window 창이 focusing된 상태가 아니라면, 캐릭터가 움직이지 않도록 처리해주는건 간단할 것이다.
▶ 기존에는 Window 창을 최소화 하거나, focusing을 주지 않아도, 방향키 입력이 먹혀서 물체가 이동했었다.
(여기서는 focusing된 window 창이 1개라도 있으면, Key가 동작하도록 작성할 것이다.)
다만 주의해야 할 점이 한 가지 존재한다.
enum class KEY_STATE
{
NONE, // 계속 안눌린 있는 상태
TAP, // 막 누른 시점
HOLD, // 계속 눌린 상태
AWAY, // 막 뗀 시점
};
TAP 혹은 HOLD 상태라면, 현재 Key 눌려져 있는 상태일 것이다.
만약 이 상태에서 창이 비활성화 된다고 가정해보자.
여기서 바로 NONE으로 Key State를 변경시켜버리면, AWAY 시점에서 호출되도록 우리가 구성했던
로직들이 동작하지 않게 될 것이다. (우리는 전에 AWAY 시점에 KEY_UP에 대한 이벤트를 정해주었기 때문에)
그래서 TAP 혹은 HOLD의 상태에서 창이 비활성화 되었다면,
AWAY를 거쳐서 NONE으로 key state가 바뀌도록 설정해주어야 한다.
CCore.cpp
...
void CCore::update()
{
Vec2 vPos = g_obj.GetPos();
// state 기능 적용, 및, HOLD 상태로 if 조건 변경 (TAP 이었음)
if (CKeyMgr::GetInst()->GetKeyState(KEY::LEFT) == KEY_STATE::HOLD)
{
vPos.x -= 300.f * CTimeMgr::GetInst()->GetfDT();
}
if (CKeyMgr::GetInst()->GetKeyState(KEY::RIGHT) == KEY_STATE::HOLD)
{
vPos.x += 300.f * CTimeMgr::GetInst()->GetfDT();
}
if (CKeyMgr::GetInst()->GetKeyState(KEY::UP) == KEY_STATE::HOLD)
{
vPos.y -= 300.f * CTimeMgr::GetInst()->GetfDT();
}
if (CKeyMgr::GetInst()->GetKeyState(KEY::DOWN) == KEY_STATE::HOLD)
{
vPos.y += 300.f * CTimeMgr::GetInst()->GetfDT();
}
g_obj.SetPos(vPos);
}
...
CKeyMgr.cpp
...
void CKeyMgr::Update()
{
// 윈도우 포커싱 알아내기
HWND hMainWnd = CCore::GetInst()->GetMainHwnd(); // 우리의 메인 윈도우 핸들 값 (지금은 안 씀)
HWND hFocusWnd = GetFocus(); // 현재 포커싱된 윈도우 핸들 값 반환
// 포커싱된 윈도우가 하나도 없으면 null이 반환된다.
// 만약 현재 Main Window가 포커싱 된 상태라면 (강의랑 조금 다른 코드)
//if (hMainWnd == hFocusWnd)
if (nullptr != hFocusWnd)
{
for (int i = 0; i < (int)KEY::LAST; ++i)
{
if (GetAsyncKeyState(g_arrVK[i]) & 0x8000)
{
if (m_vecKey[i].ePrevPush)
{
m_vecKey[i].estate = KEY_STATE::HOLD;
}
else
{
m_vecKey[i].estate = KEY_STATE::TAP;
}
m_vecKey[i].ePrevPush = true;
}
else
{
if (m_vecKey[i].ePrevPush)
{
m_vecKey[i].estate = KEY_STATE::AWAY;
}
else
{
m_vecKey[i].estate = KEY_STATE::NONE;
}
m_vecKey[i].ePrevPush = false;
}
}
}
else
{
for (int i = 0; i < (int)KEY::LAST; ++i)
{
// 이전 키 상태를 false로 변경 (state를 위해)
m_vecKey[i].ePrevPush = false;
// TAP이나 HOLD 상태인 경우, 프레임 두 번에 걸쳐서 NONE으로 바뀌도록 한 것.
if (KEY_STATE::TAP == m_vecKey[i].estate)
{
m_vecKey[i].estate = KEY_STATE::AWAY;
}
else if (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;
}
// NONE은 그대로 NONE이므로, 별도 코드 X
}
}
}
...
소스 코드의 핵심 내용들은 위와 같습니다.
이상으로 포스팅을 마치겠습니다! ⌒_⌒
'(2022) 공부 (Study) > 게임 개발 (Development)' 카테고리의 다른 글
Win32API - 출력 디렉터리 및 리소스 경로 관리 (0) | 2022.08.11 |
---|---|
[Win32API] 임시 (0) | 2022.04.20 |
[C++] 정적(static) 키워드의 개념과 활용 (0) | 2022.04.20 |
[Win32API] Bitmap에 대한 정리 (2) - bitColor 수정 및 출력 (0) | 2022.04.19 |
[Win32API] Bitmap에 대한 정리 (1) - Bitmap 구조 및 역할 (0) | 2022.04.16 |