티스토리 뷰

반응형

2021.09.12 - [C++로 게임 만들기/오목 게임 만들기] - [C++] 오목 게임 만들기 2 - 바둑판을 그리기 위한 DrawMap Class 만들기

 

[C++] 오목 게임 만들기 2 - 바둑판을 그리기 위한 DrawMap Class 만들기

2021.09.07 - [코딩 공부/C++로 게임 만들기] - C++) 오목 게임 만들기 1 C++) 오목 게임 만들기 1 현생 사느라 바빠서 오랜만에 돌아오게 된 블로그...ㅠ.ㅠ 오늘부터 C++로 오목 게임을 만드는 과정을 포

hgu-can.tistory.com

저번 시간에 바둑판을 그리기 위한 DrawMap Class를 만들었었죠~?

오늘은 그 DrawMap Class를 이용해서 타이틀 화면을 그릴거에요. 


새로운 클래스를 만들 것입니다. 

저번처럼 마우스 오른쪽 클릭해서 추가 - 클래스 

 

이번에는 GameManager라고 이름을 적은 후 확인을 눌러주세요. 

GameManager Class는 타이틀 화면을 띄우고 플레이어에게 받은 입력에 따라 게임을 진행하거나 옵션 메뉴를 띄우는 등 게임 프로그램의 흐름을 제어할 관리자 역할을 할 것입니다. 

그래서 저는 GameManager Class에서 타이틀을 그려줄 것입니다. 

 

이젠 새로운 클래스 파일이 익숙하시죠?

GameManager Class에서는 저번에 만들었던 DrawMap Class를 이용해서 타이틀 화면을 포함한 각종 맵들을 그릴 것이니까 DrawMap.h를 include 시켜주세요. 

 

그런데 여기서 iostream을 계속 써야 하는데 왜 Mecro.h는 안 쓰는건지 궁금하실 수 있어요. 

제가 첨에 그랬거든요...ㅎ

 

왜냐면 iostream 헤더파일을 가지고 있는 Mecro.h.가 이미 DrawMap Class에 인클루드되어있기 때문이에요. 

한 헤더파일을 다른 클래스에 인클루드시키면 인클루드한 헤더파일에 있는 라이브러리 헤더파일들도 다 따라와서 쓸 수 있거든요...!

헤더파일을 인클루드한 순간부터 해당 헤더파일에 있는 모든 것들(라이브러리 헤더파일, 함수, 변수 등)에 접근할 수 있어요. 

편하죠?

번거롭게 필요한 헤더파일을 일일이 써줄 필요가 없습니다. 

 

//in GameManager.h

#pragma once
#include "DrawMap.h"

class GameManager
{
public:
	GameManager();
	~GameManager();
};


//in GameManager.cpp

#include "GameManager.h"


GameManager::GameManager()
{

}

GameManager::~GameManager()
{

}

늘 하던대로 public 선언 후 생성자와 소멸자 만들어주시고, cpp파일에도 생성자와 소멸자의 본문을 만들어주세요. 

 

//in GameManager.h

#pragma once
#include "DrawMap.h"

class GameManager
{
public:
	void RunGame();
	GameManager();
	~GameManager();
};

다 하셨으면 이번에는 RunGame이라는 이름으로 함수를 만듭시다. 

 

//in GameManager.cpp

void GameManager::RunGame()
{

}

cpp 파일에서는 이렇게 적어주시면 됩니다. 

생성자와 소멸자를 만들던 형태에서 맨 앞에 반환 자료형만 적어주시면 됩니다. 

 

RunGame 함수는 메인함수에서 가장 먼저 호출되는 함수로써,

게임이 실행되면 가장 먼저 보이는 타이틀을 여기에서 그릴거에요. 

그런데 여기서 DrawMap Class의 함수를 호출하려고 하면 어떻게 할까 싶을 것입니다. 

 

헤더파일로 돌아와서 DrawMap 자료형으로 private하게 멤버변수를 만들어주세요. 

객체 지향 프로그래밍의 기본은 정보의 은닉과 캡슐화잖아요?

그렇기 때문에 어떤 값을 직접적으로 가지고 있는 변수는 숨겨줘야 합니다. 

객체 지향으로 프로그래밍 할 때 헷갈리면 변수는 private으로

함수는 public으로 선언하시면 됩니다. 


그리고 앞에 소문자로 m_을 붙이는 것은 헝가리안 표기법에서 유래된 것으로...

m_을 통해 이 변수가 멤버변수라는 것을 쉽게 알아볼 수 있습니다. 

 

코딩을 해 보시면 아시겠지만 

변수가 늘어나면 늘어날수록 점점 기억하기가 힘들어지고 헷갈리잖아요?

이것은 우리만 그런 것이 아니고 외국 사람들도 똑같이 그랬기 때문에 한 헝가리안이 이러한 표기법을 고안해냅니다...

변수명만 보고 이게 어떤 자료형을 가진 어디에 소속된 변수인지 알 수 있도록 말이죠~

그러면 나중에 값을 대입할 때 자료형이 기억 안 나서 찾으러 가는 수고를 덜 수 있잖아요. 

그래서 integer형 변수라면 int iNum; 

string형 변수라면 string strMyName; 이런 식으로 선언할 수 있습니다. 

그 중에서도 클래스의 멤버변수라면 int m_arrNumbers[10]; 이런 식으로 맨 앞에 m을 붙여주는 것이죠. 

처음엔 좀 귀찮은데 하다보면 안 쓰면 더 헷갈려서 꼭 쓰게 됩니다. 

뭐 어디까지나 권장사항이라서 죽어도 쓰기 싫으시면 꼭 쓰지는 않으셔도 괜찮습니다. 

예시로 든 것 말고도 더 많은 표기법이 있기 때문에 궁금하시면 구글 검색 추천드립니다.


클래스의 멤버변수를 이용해서 해당 클래스에 포함된 멤버함수들을 호출할 수 있습니다. 

 

타이틀 바둑판을 그리려면 GridDraw 함수가 필요하겠습니다. 

우리가 만든 GridDraw 함수의 매개변수는 시작점 x,y와 너비, 높이가 필요합니다. 

그러면 처음에 참고해서 그릴 너비와 높이를 먼저 정해주어야겠네요~

임의로 정한 숫자를 바로 넣어도 되지만 혹시 나중에 맘이 바껴서 가로 세로 길이를 바꾸게 되었을 때 좀 더 편하게 바꿔줄 수 있도록 #define을 이용해서 정해줍시다. 

 

//in Mecro.h

#pragma once

#include <iostream>
#include <Windows.h>
using namespace std;

#define WIDTH 20
#define HEIGHT 20

Mecro.h로 가서 너비와 높이값을 추가해주세요. 

가로세로값 같은 값들은 생각보다 여러 클래스에서 참조하게 되기 때문에 Mecro.h같은 곳에 선언하는 것이 좋습니다. 

#define은 C부터 공부하셨으면 다 아실테니 설명은 생략하겠습니다. 

 

그럼 이제 정말로 바둑판을 그려볼까 했지만...

그리기 전에 

바둑판은 사각형이잖아요?

그리고 바둑판 뿐만 아니라 나중에 놓을 바둑돌들도 사각형 안에 들어 있을거에요. 

그 말은 사각형을 쓸 일이 꽤 생길 것이라는 것이죠. 

그래서 사각형 구조체를 하나 만듭시다. 

함수의 인자값으로 넣어줄 때나 리턴받을때나 구조체를 쓰는 것이 편합니다. 

 

//in GameManager.h

#pragma once

#include <iostream>
#include <Windows.h>
using namespace std;

#define WIDTH 20
#define HEIGHT 20

struct Rect {
	int left;
	int right;
	int top;
	int bottom;
};

Rect라는 이름으로 위와 같이 구조체를 만들어주세요. 

사각형 또한 게임매니저와 플레이어 클래스에서 쓰게 될 것이기 때문에 Mecro.h에서 만들어주세요. 

 

//in GameManager.h

private:
	DrawMap m_DrawManager;
	Rect m_MapSize;

그리고 아까 만든 구조체로 멤버변수를 하나 만듭시다. 

이 구조체에 가로세로값을 넣어준 뒤 GridDraw의 매개변수로 넣어주면 깔끔하겠죠?!

 

//in GameManager.cpp

GameManager::GameManager()
{
	m_MapSize.left = 0;
	m_MapSize.right = WIDTH;
	m_MapSize.top = 0;
	m_MapSize.bottom = HEIGHT;
}

생성자를 이용해서 사각형 구조체에 초기 값을 할당 해줍시다. 

게임이 실행되고 GameManager가 생성되면 가장 먼저 생성자가 호출되면서 사각형도 위와 같이 초기화 될 것입니다. 

그럼 이제 값도 다 넣어줬으니까 정말로! 바둑판을 그려봅시다. 

 

//in GameManager.cpp

void GameManager::RunGame()
{
	m_DrawManager.GridDraw(0, 0, m_MapSize.right, m_MapSize.bottom);
}

만든지 한참 지났지만 아직까지도 대기중이었던...

우리의 RunGame 함수에 GridDraw 함수를 적어줍시다. 

빨간줄 없이 잘 되는 것을 보실 수 있을 것입니다. 

 

//in 소스.cpp

#include "GameManager.h"

void main()
{
	GameManager GM;
	GM.RunGame();
}

자 이제 잘 그려지는지 한 번 봐야겠죠?

약간 잊혀지고 있었던 소스.cpp로 가서 메인 함수에서 RunGame 함수를 호출합시다. 

위와 같이 수정하신 후 컨트롤+F5를 눌러서 빌드 해 봅시다. 

 

짠~~

잘 그려지죠?

뿌듯~

 


 

그런데 아래와 같이 윈도우10 이상을 쓰시면 바둑판이 절반으로 쪼그라 든 듯이 나올 수가 있어요. 

 

 

 

윈도우10부터 사용되는 유니코드가 특수문자도 1칸으로 인식해서 그렇다고 하는데...

해결하려면

 

 

콘솔창의 상태표시줄에서 마우스 우클릭을 하면 메뉴가 나옵니다. 

맨 밑에 있는 속성을 선택해 주세요. 

 

 

 

위와 같은 설정창이 나오는데

맨 밑에 있는 레거시 콘솔 사용체크를 한 다음 확인을 눌러주시면 정상적인 바둑판을 보실 수 있습니다. 

 


 

오늘은 여기까지 하고 다음 시간엔 바둑판 위에 메뉴를 띄워보겠습니다. 

예습복습 열심히 하시고 잊지 말고 돌아와주세요~~^^

 

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함