Input

이승덱·2021년 7월 30일
0

Graphics&DirectX

목록 보기
10/37

Input

#pragma once

// 입력 키를 enum과 매핑 (윈도우가 아닌 운영체제 사용할 경우 대비)
enum class KEY_TYPE
{
	UP = VK_UP,			// 윈도우가 기본으로 제공해주는 매핑된 상수
	DOWN = VK_DOWN,
	LEFT = VK_LEFT,
	RIGHT = VK_RIGHT,

	W = 'W',
	A = 'A',
	S = 'S',
	D = 'D',
};

enum class KEY_STATE
{
	NONE,
	PRESS,
	DOWN,
	UP,
	END	// Counting 용도
};

enum
{
	KEY_TYPE_COUNT = static_cast<int32>(UINT8_MAX+1),
	KEY_STATE_COUNT = static_cast<int32>(KEY_STATE::END),
};


class Input
{
	DECLARE_SINGLE(Input);
public:
	void Init(HWND hwnd);
	void Update();

	// 누르고 있을 때
	bool GetButton(KEY_TYPE key) { return GetState(key) == KEY_STATE::PRESS; }
	// 맨 처음 눌렀을 때
	bool GetButtonDown(KEY_TYPE key) { return GetState(key) == KEY_STATE::DOWN; }
	// 맨 처음 눌렀다 뗐을 때
	bool GetButtonUp(KEY_TYPE key) { return GetState(key) == KEY_STATE::UP; }

private:
	inline KEY_STATE GetState(KEY_TYPE key) { return _states[static_cast<uint8>(key)]; }

private:
	HWND _hwnd;
	vector<KEY_STATE> _states;
};
  • KEY_STATE를 이용하여 각 KEY의 상태를 PRESS,DOWN,UP,NONE으로 변경한다.
 Input::Update()
{
	HWND hwnd = ::GetActiveWindow();
	if (_hwnd != hwnd)
	{
		for (uint32 key = 0; key < KEY_TYPE_COUNT; key++)
			_states[key] = KEY_STATE::NONE;

		return;
	}

	BYTE asciiKeys[KEY_TYPE_COUNT] = {};
	if (::GetKeyboardState(asciiKeys) == false)
		return;

	for (uint32 key = 0; key < KEY_TYPE_COUNT; key++)
	{
		// 키가 눌려 있으면 true
		if (asciiKeys[key] & 0x80)
		{
			KEY_STATE& state = _states[key];

			// 이전 프레임에 키를 누른 상태라면 PRESS
			if (state == KEY_STATE::PRESS || state == KEY_STATE::DOWN)
				state = KEY_STATE::PRESS;
			else
				state = KEY_STATE::DOWN;
		}
		else
		{
			KEY_STATE& state = _states[key];

			// 이전 프레임에 키를 누른 상태라면 UP
			if (state == KEY_STATE::PRESS || state == KEY_STATE::DOWN)
				state = KEY_STATE::UP;
			else
				state = KEY_STATE::NONE;
		}
	}
}
  • 이전 상태에 따라서 지금의 상태를 변경하거나 유지한다.
  • asciiKeys[key] & 0x80을 사용하면 Key가 눌려있는지 알 수 있다.
profile
공부 기록용 블로그입니다

0개의 댓글