- ๊ธฐ์กด ํค ์ ๋ ฅ ๋ฐฉ์์ ๋ฌธ์
์ฐ์ ๋ฐ์ํ ์ ์๋ ์ฒซ ๋ฒ์งธ ์ํฉ์ A์ B ๋ฌผ์ฒด๊ฐ ์ด๋ํ๋ ๊ฒ์์์ ํค ๋งค๋์ ๊ฐ ์๋ค๋ฉด, ๊ฐ ๋ฌผ์ฒด๋ ์์ ์ ํค ์ ๋ ฅ์ ๊ฐ๋ณ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ฒ ๋๋ค. ๊ทธ๋ ๊ฒ ๋ ๊ฒฝ์ฐ ํค๋ฅผ ์ฒ๋ฆฌํ๋ ์ ๋ฐฑ ๋ฒ์ ์ํฉ ์ค์ A ๋ฌผ์ฒด๋ ํ์ฌ ํ๋ ์์์ ์ด๋์ ์ฒ๋ฆฌํ์ง๋ง, B ๋ฌผ์ฒด๋ ๋ค์ ํ๋ ์์์ ์ด๋์ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ธธ ์ ์๋ค. ์ด๋ ์ ์ ์ ์ ์ฅ์์ A ๋ฌผ์ฒด๋ ๋จผ์ ์ด๋ํ๊ณ , B ๋ฌผ์ฒด๋ ์ฝ๊ฐ์ ์ง์ฐ ํ์ ์ด๋ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ๋๋ค.
๋ ๋ฒ์งธ ์ํฉ์ ์ฐ๋ฆฌ๊ฐ ์ ํ ๊ฒ์์ ํ๋ค๊ณ ๊ฐ์ ํ์. ์งง๊ฒ ์ ํํ ๋์ ๊ธธ๊ฒ ์ ํ๋ฅผ ๋๋ฅผ ๋ ๋ ๋ผ๊ฐ๋ ํญ๊ณผ ๊ฑฐ๋ฆฌ๊ฐ ๋ค๋ฅด๊ฒ ์ค๊ณํ๋ ค๊ณ ํ๋ค๋ฉด, ์ด๋ฅผ ์ด๋ป๊ฒ ๊ตฌํํ ๊ฒ์ธ๊ฐ?
ํ์ฌ ์ฐ๋ฆฌ๊ฐ ์์
ํ๋ ๊ตฌ์กฐ๋ ๋งค ์๊ฐ์๊ฐ UPDATE ํจ์๋ฅผ ํ์ธํ๊ณ , ๋ชจ๋ ์
๋ฐ์ดํธ๊ฐ ๋๋๋ฉด ์ด ๋ณ๊ฒฝ์ ์ ๋ฐ์ํ์ฌ ๊ทธ๋ฆฌ๊ณ ์๋ค. ์ด ๊ณผ์ ์ด 1ํ๋ ์์ ๊ณผ์ ์ด๊ณ ์ด ํ ํ๋ ์์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ DT๋ผ๊ณ ํจ. ex) 900ํ๋ ์์ด๋ผ ํ๋ฉด 1์ด์ 900๋ฒ ์์
ํจ
์ฐ๋ฆฌ๋ ํ ํ๋ ์ ์๊ฐ(DT)์ด ์ง๋ ํ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ณผ ์ ์๊ธฐ์, ๊ทธ ๋ฌผ์ฒด๊ฐ ๋ฐ๋ก๋ฐ๋ก ์ด๋ํ๋ ๊ฒ์ ๋ณผ ์ ์์. A์ ๋ฌผ์ฒด๊ฐ ๋จผ์ ์ด๋ํ๊ณ ๊ทธ ํ B๊ฐ ์ด๋ํ๋๋ผ๋, ํ DT์์์ ์ผ์ด๋ฌ์ผ๋ฉด ์ด๋ ์ ์ ๊ฐ ๋ดค์ ๋ ๊ฑ ๋์์ ์์ง์ด๋ ๊ฒ๊ณผ ๋ค๋ฆ ์์. ํ ํ๋ ์์์ ์ ์ฉ๋ ํค๋ ๋ฌด์กฐ๊ฑด ๊ฐ์ ์ด๋ฒคํธ๋ก ์ฒ๋ฆฌ๋์ด์ผ ํ๋ค.
- Key Manager๋ฅผ ์ฌ์ฉํ๋ ์ด์
1) ํ๋ ์ ๋๊ธฐํ : ๋์ผ ํ๋ ์์์ ์ผ์ด๋ ์ผ์ ๊ฐ์ ํค์ ๋ํด ๋์ผํ ์ด๋ฒคํธ๋ก ์ฒ๋ฆฌํด์ผ ํจ.
2) ํค ์ ๋ ฅ์ ์ฌ๋ฌ ์ด๋ฒคํธ๋ก ๋๋ ์ฒ๋ฆฌ : TAP, HOLD, AWAY, NONE
// KeyManager.h
enum class KEY_STATE {
NONE,
TAP,
HOLD,
AWAY,
};
enum class KEY {
LEFT,
RIGHT,
UP,
DOWN,
Q,
W,
E,
R,
T,
Y,
U,
I,
O,
P,
A,
S,
D,
F,
G,
Z,
X,
C,
V,
B,
ALT,
CTRL,
LSHIFT,
SPACE,
ENTER,
ESC,
LAST,
};
struct keyInfo {
KEY_STATE state;
bool prev;
};
class KeyManager
{
SINGLE(KeyManager);
private:
vector<keyInfo> vecKey;
public:
void init();
void update();
public:
KEY_STATE GetKeyState(KEY key) { return vecKey[(int)key].state; }
};
1) ํค ์ ๋ ฅ ์ด๋ฒคํธ ์ ์ โ enum class KEY_STATE
ํค ์ด๋ฒคํธ๋ฅผ ์ ์ํ๋ค.
NONE - ์ด์ ํ๋ ์์๋ ๋๋ฆฌ์ง ์๊ณ , ํ์ฌ ํ๋ ์์์๋ ๋๋ฆฌ์ง ์์.
TAP - ์ด์ ํ๋ ์์๋ ๋๋ฆฌ์ง ์๊ณ , ํ์ฌ ํ๋ ์์ ๋ง ๋๋ฆผ.
HOLD - ์ด์ ํ๋ ์์๋ ๋๋ ธ๊ณ , ํ์ฌ ํ๋ ์์๋ ๋๋ฆผ.
AWAY - ์ด์ ํ๋ ์์ ๋๋ ธ๋๋ฐ, ํ์ฌ ํ๋ ์์์๋ ๋๋ฆฌ์ง ์์. (๋ง ๋)
2) ์ง์ํ ํค ์ ์ โ enum class KEY
์ด ํ๋ก๊ทธ๋จ ๋ด์์ ์ด๋ค ํค๋ฅผ ์ฒ๋ฆฌํ ๊ฒ์ธ์ง ์ ์ํ์.
3) ํค ์ ๋ณด ๊ตฌ์กฐ์ฒด โ struct keyInfo
ํค ์ํ๊ฐ(state)๊ณผ ์ด์ ํ๋ ์์์ ํค๊ฐ ๋๋ ธ๋ ์ง(prev)์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ๊ณ ์๋ค.
4) KeyManager Class
vector<keyInfo> vecKey โ ํค ์ํ ์ ๋ณด๋ ๋ฒกํฐ๋ก ๊ด๋ฆฌํ๋ค.
KEY_STATE GetKeyState(KEY key) โ ํน์ ํค์ ํ์ฌ ์ํ๋ฅผ ๋ฐํํ๋ ํจ์
// KeyManager.cpp
#include "pch.h"
#include "KeyManager.h"
#include "Core.h"
int 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,
};
KeyManager::KeyManager()
{
}
KeyManager::~KeyManager()
{
}
void KeyManager::init()
{
for (int i = 0; i < (int)KEY::LAST; ++i) {
vecKey.emplace_back(keyInfo{ KEY_STATE::NONE, false });
}
// std::cout << "vecKey size after init: " << vecKey.size() << std::endl;
}
void KeyManager::update()
{
// HWND mainWnd = Core::Instance()->getMainHandle();
HWND hWnd = GetFocus();
// ์๋์ฐ ํฌ์ปค์ฑ ์ค์ผ ๋
if (nullptr != hWnd) {
// ๋ชจ๋ ํค์ ๋ํด์
for (int i = 0; i < (int)KEY::LAST; ++i) {
if (GetAsyncKeyState(arrVK[i]) & 0x8000) { // ํค๊ฐ ๋๋ ค์๋ค
if (vecKey[i].prev) { // ์ด์ ์๋ ๋๋ ค์์๋ค.
vecKey[i].state = KEY_STATE::HOLD;
}
else {
vecKey[i].state = KEY_STATE::TAP;
}
vecKey[i].prev = true;
}
else { // ํค๊ฐ ์๋๋ ค์๋ค.
if (vecKey[i].prev) { // ์ด์ ์๋ ๋๋ ค์์๋ค.
vecKey[i].state = KEY_STATE::AWAY;
}
else {
vecKey[i].state = KEY_STATE::NONE;
}
vecKey[i].prev = false;
}
}
}
else { // ํฌ์ปค์ฑ ์๋ ๋
for (int i = 0; i < (int)KEY::LAST; ++i) {
vecKey[i].prev = false;
if (KEY_STATE::TAP == vecKey[i].state || KEY_STATE::HOLD == vecKey[i].state)
vecKey[i].state = KEY_STATE::AWAY;
else if (KEY_STATE::AWAY == vecKey[i].state)
vecKey[i].state = KEY_STATE::NONE;
}
}
}
๋ด๊ฐ ๋ง๋ ํค์ ์ค์ ๊ฐ์ํค๋ฅผ ์กฐํฉํด์ผ ํ ํ์๊ฐ ์๋ค โ arrVK()
์ค์ ์๋์ฐ ๋ด์ ๊ฐ์ํค์ ์์คํค์ฝ๋๋ฅผ ์ด์ฉํ์ฌ ์์ฑํ๋๋ก ํ๋ค.
ํค ๋งค๋์ ์ ์ด๊ธฐํ ํจ์์์๋ ๊ฐ ํค์ ๋ํ ์ ๋ณด๋ฅผ NONE, false๋ก ์ด๊ธฐํํ์ฌ ํค ์ ๋ณด ๋ฒกํฐ์ ์ฝ์ ํ๋ค.
์ ๋ฐ์ดํธ ํจ์์์๋ ์๋์ฐ ํฌ์ปค์ฑ์ ์์๋ด์ผ ํ๋๋ฐ '์๋์ฐ ํฌ์ปค์ฑ'์ด๋ ํ์ฌ ์ ์ ๊ฐ ์๋์ฐ ์ฐฝ์ ํฌ์ปค์ฑ ์ค์ธ๊ฐ? ์ ํด๋นํ๋ ๋ด์ฉ์ด๋ค. ๋ง์ฝ ์๋์ฐ ์ฐฝ์ด ๋ด๋ ค๊ฐ์์๋ ๋ถ๊ตฌํ๊ณ ํค ์ ๋ ฅ์ ๋ฐ๋ ์ํ๋ผ๋ฉด ๊ฒ์ ๋ด์์ ์ด์ํ๊ฒ ์ ์ฉ๋ ์ ์๋ค.
ํ์ฌ ๋ฉ์ธ ์ฐฝ์ผ๋ก๋ง ํฌ์ปค์ฑํ๋ ค๋ฉด ์ฃผ์์ผ๋ก ์ฒ๋ฆฌ๋ HWND mainWnd = Core::Instance()->getMainHandle(); ์ ์ฌ์ฉํ๋ฉด ๋๋ ํ์ฌ ํ๋ก๊ทธ๋จ์์๋ ๋ง๋ค์ด์ง ๋ชจ๋ ์ฐฝ์ ๋ํด์ ์ ๋ ฅ์ ๋ฐ๊ธฐ ์ํจ์ผ๋ก hWnd๊ฐ null์ด ์๋ ๋๋ง ํค ์ ๋ ฅ์ ๋ฐ๋๋ก ํ๋ค.
์๋์ฐ ํฌ์ปค์ฑ ์ค์ผ ๋ ๋ชจ๋ ํค์ ๋ํด์ ํ์ฌ ๋๋ ธ๋์ง์ ์๋๋ ธ๋์ง, ์ด์ ์ ๋๋ ธ๋์ง์ ์๋๋ ธ๋์ง๋ฅผ ์ฒดํฌํด ๊ฐ ์ํ ์ด๋ฒคํธ๋ฅผ ์ค์ ํ๋ค.
ํค ๋งค๋์ ๋ฅผ Core.cpp์ ์ ์ฉํ๋ฉด ๋๋๋ฐ ์๋์ ๊ฐ๋ค.
// Core.cpp
#include "KeyManager.h" // ์ถ๊ฐ
int Core::Init(HWND _handle, POINT _ptResolution)
{
// ...
TimeManager::Instance()->Init();
KeyManager::Instance()->init(); // ์ถ๊ฐ
// ...
}
void Core::Progress()
{
// Manager update
TimeManager::Instance()->update();
KeyManager::Instance()->update(); // ์ถ๊ฐ
Update();
Render();
}
void Core::Update()
{
Vec2 vPos = obj.getPos();
// ์์
if (KeyManager::Instance()->GetKeyState(KEY::LEFT)==KEY_STATE::AWAY) {
vPos.x -= 200.f * TimeManager::Instance()->getfDT();
}
if (KeyManager::Instance()->GetKeyState(KEY::RIGHT) == KEY_STATE::AWAY) {
vPos.x += 200.f * TimeManager::Instance()->getfDT();
}
obj.setPos(vPos);
}
'๐ค Study > winAPI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[winAPI 08] Object (0) | 2024.06.05 |
---|---|
[winAPI 07] Scene & Scene Manager (1) | 2024.06.04 |
[winAPI 05] Double Buffering (0) | 2024.06.04 |
[winAPI 04] Timer (0) | 2024.04.09 |
[winAPI 03] Core class & Singleton (0) | 2024.04.08 |