게임의 맵을 만드려면 Tile이 필요합니다.
이 Tile을 배치할 수 있는 Tool을 만들어 봅시다.
우선 Tile이 필요하겠죠?
Tile 역할을 해 줄 CTile 클래스를 만듭니다.
멤버 m_pTexture는 Tile의 외형으로
위와 같은 이미지 파일을 가리키는 멤버입니다.
멤버 m_TextureIdx는 m_pTexture가 가리키는 이미지 파일을
일정한 단위로 나누어서 인덱스로 접근하기 위한 멤버입니다.
위 그림처럼 말이죠.
위에서 보이는 텍스처로 사용할
이미지 파일의 크기는 954 x 954입니다.
그래서 하나의 인덱스 안에 있는 Tile의 크기는
954 / 4 = 238, 약 238 x 238 정도이죠.
이제 cpp 파일을 살펴봅시다.
생성자에서 Tile의 크기를 지정해 주고 있습니다.
위의 있는 이미지 파일의 경우,
Tile 하나의 크기는 약 238 x 238 정도이므로
TILE_SIZE라는 매크로를 만들어 Tile의 크기를 나타내주었습니다.
CScene_Tool이라는 클래스를 만들어주었습니다.
시작 Scene이나 종료 Scene과 같이
게임에는 다양한 Scene가 존재하죠.
여기서 CScene_Tool은 맵을 제작하는
Scene입니다. 에디터 모드라고 생각하면 되겠네요.
Enter 함수에서 CResMgr의 LordTexture 함수를 호출하여
상대 경로 안에 texture 폴더 속 tile.bmp 파일을 불러옵니다.
이후 이중 for 문을 돌려 16개의 Tile 객체를 만듭니다.
( 아까 보았던 이미지 파일의 경우 16개의 Tile을 표현할 수 있기 때문입니다. )
그리고 각 Tile마다 위칫값을 세팅해 줍니다.
0행부터 시작하여 Tile의 크기만큼
0 ~ 3열의 위칫값을 세팅해 주고,
이를 3행까지 반복하게 되겠죠.
그리고 불러왔던 텍스처를 적용해 주고
AddObject를 통해 등록을 해 줌으로써
해당 오브젝트를 Scene이 관리할 수 있도록 합니다.
CCore의 GetResolution 함수를 통해
게임 화면의 해상도를 구하고,
이를 반으로 나눈 위칫값을 카메라가 바라볼 수 있도록 합니다.
화면의 중앙에 카메라를 이동시키는 것이죠.
다시 CTile의 cpp 파일로 돌아와서,
이미지 파일을 통해 Tile을 화면상에 표현하려면
render 함수를 구현해야겠죠.
m_pTexture가 nullptr이거나, m_TextureIdx가
1보다 작거나 같으면 render 함수를 진행하지 않도록 합니다.
Tile을 render하기 위해서는 텍스처가 있고
정상적인 인덱스에 접근하고 있어야겠죠.
텍스처의 Width값과 Height값을 구합니다.
Width값을 Tile 크기로 나누어 주면
열의 개수를 알 수 있고, Height값을
Tile 크기로 나누어 주면 행의 개수를 알 수 있겠죠.
33번째 코드를 보면
m_TextureIdx의 값을 iMaxColSize로 나누어
몫을 구하고 있습니다.
이는 적용하고자 하는 Tile의 인덱스가
어떤 행에 존재하는지 알 수 있도록 한 것이죠.
만약 14번 인덱스의 Tile을 사용하고 싶어
m_TextureIdx의 값을 14로 세팅해 준 상태에서
iMaxRowSize값이 4인 경우, 몫이 3이므로
3번 행에 14번 인덱스가 존재하는 것을 알 수 있게 되죠.
34번째 코드는 % 연산을 하여 나머지를 통해
적용하고자 하는 Tile의 인덱스가
어떤 열에 존재하는지 알 수 있도록 한 겁니다.
m_TextureIdx의 값을 14로 세팅해 준 상태에서
iMaxColSize값이 4인 경우,
2번 열에 14번 인덱스가 존재하는 것을 알 수 있습니다.
iCurCol 같은 경우 나머지를 구하고 있기 때문에
아무리 큰 수가 m_TextureIdx값으로 들어와도
문제가 되지는 않습니다.
그러나 iCurRow은 몫을 구하기 때문에
m_TextureIdx값이 너무 큰 수로 설정되면
존재하지 않는 위칫값을 얻게 되므로 위험하죠.
그래서 iCurRow가 iMaxRowSize보다
크거나 같으면 프로그램이 멈추도록 하였습니다.
이후 vRenderPos에 카메라의 위칫값을 저장하고,
CTile의 생성자에서 설정해주었던
Tile 하나의 크기를 vScale에 저장해 줍니다.
그리고 BitBlt 함수를 통해 실제 화면상에
Tile을 그릴 수 있도록 합니다.
2 ~ 3번째 인자는 Tile이 그려질 위치의 왼쪽 상단 좌푯값입니다.
여기서는 화면 왼쪽 상단 구석에 Tile을 그려줄 것이므로
vRenderPos의 x값과 y값을 그대로 넣습니다.
4 ~ 5번째 인자는 원본 텍스처 파일에서
얼마만큼의 크기를 가져올 것인지 설정하는 겁니다.
여러 개의 Tile이 모여있는 텍스처 파일에서
원하는 Tile 한 칸을 얻어오기 위해서는
238 x 238만큼 읽어오면 되겠죠.
그래서 vScale의 x값과 y값을 넣습니다.
7 ~ 8번째 인자는 원본 텍스처 파일의
어디 좌푯값부터 읽어올지 결정하기 위한 인자입니다.
iCurCol값에 TILE_SIZE을
곱하면 iCurCol의 x 좌푯값을 알 수 있겠죠?
이를 통해 원본 텍스처로부터 읽어올 Tile의 x값을 얻습니다.
마찬가지로
iCurRow값에 TILE_SIZE을
곱하면 iCurRow의 y 좌푯값을 알 수 있겠죠?
이를 통해 원본 텍스처로부터 읽어올 Tile의 y값을 얻습니다.
SRCCOPY 매크로를 인자로 넘겨
원본 텍스처 파일을 읽어와 덮어씁니다.
이제 SceneMgr 클래스에서
37번째 줄에 있는 코드처럼
m_pCurScene에 m_arrScene[(UINT)SCENE_TYPE::TOOL]을
대입하여 프로그램을 실행합니다.
프로그램 시작 시, 원하던 Tile이
화면상에 출력되는 것을 확인할 수 있습니다.
강의 출처 : https://www.youtube.com/watch?v=Mn7CQUpk68o
'Win32 API > 기초' 카테고리의 다른 글
Win32 API 기초 : Unity Build (0) | 2024.11.23 |
---|---|
Win32 API 기초 : Camera (3) (0) | 2024.10.06 |
Win32 API 기초 : Camera (2) (4) | 2024.10.05 |
Win32 API 기초 : Camera (1) (2) | 2024.10.04 |
Win32 API 기초 : Animation (4) (0) | 2024.09.01 |