0. 더미 코드를 제거한 이전 코드
더보기
#include "framework.h"
#include "GameCoding.h"
#define MAX_LOADSTRING 100
int mousePosX;
int mousePosY;
// 전역 변수:
HINSTANCE hInst; // 현재 인스턴스입니다.
// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
// TODO: 여기에 코드를 입력합니다.
// 1) 윈도우 창 정보 등록
MyRegisterClass(hInstance);
// 2) 초기화
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
MSG msg;
//3) 메인 루프 ;
while (::GetMessage(&msg, nullptr, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//
// 함수: MyRegisterClass()
//
// 용도: 창 클래스를 등록합니다.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex{};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMECODING));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = L"GameCoding";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// 함수: InitInstance(HINSTANCE, int)
//
// 용도: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
// 주석:
//
// 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
// 주 프로그램 창을 만든 다음 표시합니다.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
RECT windowRect = { 0, 0, 800, 600 };
::AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, false);
HWND hWnd = CreateWindowW(L"GameCoding", L"Client", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
return FALSE;
::ShowWindow(hWnd, nCmdShow);
::UpdateWindow(hWnd);
return TRUE;
}
//
// 함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 용도: 주 창의 메시지를 처리합니다.
//
// WM_COMMAND - 애플리케이션 메뉴를 처리합니다.
// WM_PAINT - 주 창을 그립니다.
// WM_DESTROY - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 메뉴 선택을 구문 분석합니다:
switch (wmId)
{
case IDM_EXIT:
::DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
About, 창의 이름 등등을 제거한 기본 코드.
0-1. Main 함수
while (true)
{ // 메시지가 있을 때 WndProc를 구동
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
// 게임 로직 구동
}
}
메인 함수 내의 메인 루프를 수정한다.
if 문을 사용하여 메시지가 있을 때만 WndProc를 사용하도록 한다.
1. 미리 컴파일된 헤더 설정
위와 같이 설정하고 저장한다.
이후 솔루션 탐색기 - 추가 - 클래스에서 pch.h와 pch.cpp를 만든다.
그리고 pch.cpp의 미리 컴파일된 헤더 설정을 만들기로 바꾸고 저장한다.
1) pch.h
#pragma once
#include "Types.h"
#include "Enums.h"
#include "Defines.h"
#include <windows.h>
#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;
GameCoding.cpp에 include 해준다.
2) Types.h
#pragma once
using int8 = __int8;
using int16 = __int16;
using int32 = __int32;
using int64 = __int64;
using uint8 = unsigned __int8;
using uint16 = unsigned __int16;
using uint32 = unsigned __int32;
using uint64 = unsigned __int64;
4. Game.h ; 게임의 베이스 코드
#pragma once
class Game
{
public:
Game();
~Game();
public:
void Init();
void Update();
void Render();
private:
HWND _hwnd = {};
HDC _hdc = {};
};
앞으로도 Game 클래스는 기본적으로 Init(초기화), Update(업데이트), Render(렌더링) 세 개의 역할을 가진다.
5. GameCoding.cpp
1) 초기화
HWND g_hWnd;
핸들 번호를 들고있는 값이다. 전역변수로 선언한다.
그리고 아래에서 InitInstance를 찾아
g_hWnd = hWnd;
hWnd를 전역변수의 값으로 들고있게 저장한다.
이후에 메인 루프 위쪽에서 초기화를 한다.
// 2) 초기화
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
Game game;
game.Init(g_hWnd);
MSG msg;
//3) 메인 루프 ;
while (true)
{ // 메시지가 있을 때 WndProc를 구동
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
// 게임 로직 구동
game.Update();
game.Render();
}
}
메인 루프 내에서 업데이트와 렌더링을 진행한다.
2) X버튼을 누르면 프로그램 종료하기
while 문을 다음과 같이 수정한다.
MSG msg = {};
//3) 메인 루프 ;
while (msg.message != WM_QUIT)
6. Game.cpp
#include "pch.h"
#include "Game.h"
Game::Game()
{
}
Game::~Game()
{
}
void Game::Init(HWND hwnd)
{
_hwnd = hwnd;
_hdc = ::GetDC(hwnd);
}
void Game::Update()
{
}
void Game::Render()
{
}
'Windows API & 게임 수학' 카테고리의 다른 글
1-6. 오브젝트(Object) 설계 (1) - 플레이어, 투사체, ObjectManager (0) | 2023.10.17 |
---|---|
1-5. 더블 버퍼링 (Double Buffering) (0) | 2023.10.17 |
1-4. 게임을 위한 프레임워크 제작하기(3) - Scene, SceneManager (1) | 2023.10.16 |
1-3. 게임을 위한 프레임워크 제작하기(2) - TimeManager, InputManager (1) | 2023.10.16 |
1-1. 기본 템플릿 분석 (1) | 2023.10.16 |