프레임워크 제작의 목표는 게임 메인 루프와 입력, 시간 관리를 체계적으로 만들기 위함입니다. 예제 코드에서는 PeekMessage와 GetMessage를 비교하여, 논블로킹 환경에서 메시지 처리를 개선하고 게임의 로직을 정상적으로 수행할 수 있도록 메인 루프를 수정하는 것이 핵심입니다.
코드:
MSG msg = {};
while (msg.message != WM_QUIT)
{
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
// 게임 로직
}
}
설명:
1. MSG msg = {};
while (msg.message != WM_QUIT)
WM_QUIT 메시지가 발생할 때 루프를 빠져나가 프로그램을 종료합니다.if (::PeekMessage(..., PM_REMOVE))
PM_REMOVE: 메시지를 가져온 뒤 제거합니다. ::TranslateMessage(&msg)
::DispatchMessage(&msg)
else
강의에서는 MainGame, Manager, Header 폴더를 나누어 정리했습니다.
Game.h, Game.cpp)TimeManager.h, InputManager.h)Utils.h, Types.h, Defines.h, Enums.h 등#pragma once
#define MAX_FPS 60
enum class KeyState { None, Press, Down, Up };
#pragma once
using int32 = __int32;
struct Pos
{
float x = 0;
float y = 0;
};
pch.h:
#pragma once
#include "Types.h"
#include "Defines.h"
#include "Enums.h"
#include <Windows.h>
#include <vector>
#include <string>
설명:
Utils.h:
#pragma once
#include "Types.h"
#include <Windows.h>
#include <string>
class Utils
{
public:
static void DrawText(HDC hdc, Pos pos, const std::wstring& str);
};
Utils.cpp:
void Utils::DrawText(HDC hdc, Pos pos, const std::wstring& str)
{
::TextOut(hdc, static_cast<int32>(pos.x), static_cast<int32>(pos.y), str.c_str(), str.size());
}
DECLARE_SINGLE(InputManager)
void Update();
Update 함수:
if (::GetKeyboardState(asciiKeys))
{
for (uint32 key = 0; key < KEY_TYPE_COUNT; key++)
{
if (asciiKeys[key] & 0x80) { /* 상태 업데이트 */ }
}
}
프레임 시간과 FPS를 계산합니다.
void Update()
{
uint64 currentCount;
::QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(¤tCount));
_deltaTime = (currentCount - _prevCount) / static_cast<float>(_frequency);
_prevCount = currentCount;
}
Game.h:
void Init(HWND hwnd);
void Update();
void Render();
Game.cpp:
void Game::Render()
{
uint32 fps = GET_SINGLE(TimeManager)->GetFps();
wstring str = format(L"FPS({0})", fps);
::TextOut(_hdc, 20, 10, str.c_str(), str.size());
}
pch.h에 CRT 디버깅 기능을 활성화:
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif