WIN32 Timer, KeyManager
카테고리: WINAPI
태그: KeyManager WIN32 Windows WINAPI
7일차
- Default
- Client.h
- framework.h
- Resouce.h
- targetver.h
- Engine
- Header
- define.h
- struct.h
- Core
- CCore.cpp
- CCore.h
- Manager
- KeyMgr
- CkeyMgr.cpp
- CkeyMgr.h
- TimeMgr
- CTimeMgr.cpp
- CTimeMgr.h
- KeyMgr
- Object
- CObject.cpp
- CObject.h
- Header
- 리소스 파일
- main.cpp
- pch.h.
- struct.h
- 이번에 한 것은 KeyManager이다. 왜 필요한가?
- 한 프레임에 모든 키입력과 관련된 이벤트가 필요하기 때문
- KeyDown(키를 딱 누른 순간), KeyHold(키를 계속 누르고 있다), KeyUp(키를 눌렀다가 막 올린 상태) 와 같은 이벤트 처리가 필요하다.
- 또한, 현재 사용자가 보고있는 윈도우가 우리가 만든 윈도우가 아닐때에는 키 입력을 받지 않아야 한다. 하지만, 기본 세팅은 메인 윈도우(우리가 보고 있는 윈도우)가 아님에도 키 입력을 받으니 그걸 처리해줘야한다.
- CkeyMgr.h
#pragma once
//#include 거는 거 불편함. 그래서.
//순차적이기 때문에, 한 프레임 시간이 지났을 때. DT라는 시간이 지난만큼 각각 변경점을 적용함 -> 그렇게 그린 걸 우리가 봄
//A 물체를 이동시켰을 때, B물체보다 먼저 일어난 건가? 그건 아니지 않나? 그런데 절차지향대로라면 그렇게 됨.
//이 모든 작업이 완료 됐을 때 모두가 동시에 일어난 사건으로 봐야만 함.
//만약 누구는 처리 받고, 누구는 처리 받지 못할수도 있음.
//
//따라서 KeyManager가 필요한 이유
//1. 프레임 동기화. 한 프레임에 모두 일어나야 함.
//2. 윈도우에서 만들어준 함수로는 구체적인 이벤트가 적용되어 있지 않음
//EX) 엔터키가 눌려있다만 궁금한 게 아니라, 이번에 눌렸다(Down), 이번에 뗏다(Up) <- 이런 것도 지정해줘야함.
#include "define.h"
//키 상태.
enum class KEY_STATE {
TAP, //막 누른 시점
HOLD, //누르고 있는
AWAY, //막 뗀 시점
NONE, // 눌리지 않은 상태. 이전에도 눌리지 않은 상태.
};
//지원해줄 수 있는 키
enum class KEY {
LEFT,
RIGHT,
UP,
DOWN,
Q,
W,
E,
R,
T,
Y,
U,
I,
O,
P,
A,
S,
D,
F,
G,
H,
J,
K,
L,
Z,
X,
C,
V,
B,
N,
M,
ALT,
CTRL,
LSHIFT,
SPACE,
ENTER,
ESC,
LAST,
};
struct tKeyInfo{
KEY_STATE eState; //키의 상태값.
bool bPrevPush; //이전에 이 키가 눌렸는지 안 눌렸는지
};
class CkeyMgr
{
SINGLE(CkeyMgr);
private:
//벡터의 INDEX값이, 곧 KEY값.
vector<tKeyInfo> m_vecKey;
public:
void init();
void update();
public:
KEY_STATE GetKeyState(KEY _eKey) {
return m_vecKey[(int)_eKey].eState;
};
};
- CkeyMgr.cpp
#include "pch.h"
#include "CkeyMgr.h"
#include "CCore.h"
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',
'H',
'J',
'K',
'L',
'Z',
'X',
'C',
'V',
'B',
'N',
'M',
VK_MENU,
VK_CONTROL,
VK_LSHIFT,
VK_SPACE,
VK_RETURN,
VK_ESCAPE,
//LAST,
};
CkeyMgr::CkeyMgr() {
}
CkeyMgr::~CkeyMgr() {
}
void CkeyMgr::init()
{
for (int keyIDX = 0; keyIDX < (int)KEY::LAST; keyIDX++) {
m_vecKey.push_back(tKeyInfo{ KEY_STATE::NONE, false });
}
//아래처럼 상태확인, 이전에 눌렸는지.
//m_vecKey[(int)KEY::LEFT].bPrev
//m_vecKey[(int)KEY::LEFT].eState
}
//뭔가를 하고 있다가, 창을 바꾸면 키를 떼지는 것까지는 구현해야하지 않을까?
//TAB상태였던 애는 바로 떼진 AWAY로 가야함 -> NONE
//HOLD였던 애는 AWAY로 갔다가 -> NONE
void CkeyMgr::update() {
//윈도우 포커싱 알아내기
HWND hMainWnd = CCore::GetInstance()->GetMainHwnd();
HWND hWnd = GetFocus();//현재 포커싱 되어 있는 윈도우의 핸들값을 알려줌.
//지금 포커싱 중인게, 이 프로그램의 메인 윈도우라면 같은지 아닌지만 확인해주면 됨.
//윈도우 포커싱 중일 때, 키 이벤트 동작.
if (nullptr != hWnd) {
for (int keyIDX = 0; keyIDX < (int)KEY::LAST; keyIDX++) {
//키가 눌렸다면.
if (GetAsyncKeyState(g_arrVK[keyIDX]) & 0x8000) {
if (m_vecKey[keyIDX].bPrevPush) {
//이전에 눌려있었다.
m_vecKey[keyIDX].eState = KEY_STATE::HOLD;
}
else {
//이전에 눌려있지 않았다.
m_vecKey[keyIDX].eState = KEY_STATE::TAP;
}
m_vecKey[keyIDX].bPrevPush = true;
}
else {//현재 키가 눌려있지 않다면.
if (m_vecKey[keyIDX].bPrevPush) {
//이전에 키가 눌려있다면.
m_vecKey[keyIDX].eState = KEY_STATE::AWAY;
}
else {
//이전에 키가 눌려있지 않았다면.
m_vecKey[keyIDX].eState = KEY_STATE::NONE;
}
m_vecKey[keyIDX].bPrevPush = false;
}
}
}
else {
//윈도우 포커싱 해제 상태
for (int keyIDX = 0; keyIDX < (int)KEY::LAST; keyIDX++) {
m_vecKey[keyIDX].bPrevPush = false;
if (m_vecKey[keyIDX].eState == KEY_STATE::TAP || m_vecKey[keyIDX].eState == KEY_STATE::HOLD) {
m_vecKey[keyIDX].eState = KEY_STATE::AWAY;
}
else if (m_vecKey[keyIDX].eState == KEY_STATE::AWAY) {
m_vecKey[keyIDX].eState = KEY_STATE::NONE;
}
}
}
}
- CCore.cpp의 update함수
void CCore::update()
{
Vec2 vPos = g_obj.GetPos();
//비동기 키 입출력 함수. <- 코드가 바로 실행됨. 백그라운드여도 바로 수행됨
//return 되는 건 어느정도 상태 값을 알려줌.
//여기까지 와야, 이 키가 어떤 상태인지 알 수 있음. 우리 프로그램은 매 순간 update를 거침.
//모든 업데이트가 끝나면, 변경점을 적용시켜 물체들을 그려냄.
if (CkeyMgr::GetInstance()->GetKeyState(KEY::LEFT) == KEY_STATE::HOLD) {
vPos.x -= 200.f * fDT;
}
if (CkeyMgr::GetInstance()->GetKeyState(KEY::RIGHT) == KEY_STATE::HOLD) {
vPos.x += 200.f * fDT;
}
g_obj.SetPos(vPos);
}
댓글 남기기