본문 바로가기
코스웨어

2015-11-19 Win32 API 개인업무일지 - 천정호

by 알 수 없는 사용자 2015. 11. 20.
728x90
반응형

Win32 API PushPush Game


간단한 게임의 지도를 그리는 방법

배열을 이용하여 벽과 길 그 이외의 다른것을 문자로 대치하여 그린다

아래의 배열과 같이 #은 벽, @는 캐릭터, B는 박스, .은 게임상의 점 등으로 이루어진다.

static UCHAR ucStage_Map[STAGE][YFRAME][XFRAME + 1] = {

{ "###############", 

"#@      ##    #", 

"###.  # ## ## #", 

"###   # ## ## #", 

"### # # ## ## #", 

"### # # ## ## #", 

"#      B      #", 

"# # ######### #", 

"#             #", 

"###############" },


{ "###############", 

"#@    B. #    #", 

"# ####   # #  #", 

"# .      # #  #", 

"#       .     #", 

"# B    #####  #", 

"#       B     #",

"# ## # # # ## #", 

"#             #", 

"###############" }

};


맵을 그리는 함수 구현 - Load_Map()

위의 배열을 바탕으로 게임의 초기 화면을 그릴수 있게 맵을 복사한다.

void Load_Map() {

int iX_Count;

int iY_Count;


uiScore = 0;

uiDot_Num = 0;

// Background Drawing

for (iX_Count = 0; iX_Count < XFRAME; iX_Count++) {

for (iY_Count = 0; iY_Count < YFRAME; iY_Count++) {


if (ucStage_Map[uiStage][iY_Count][iX_Count] == '.') {

++uiDot_Num;

}


if (ucStage_Map[uiStage][iY_Count][iX_Count] == '@') {

iX_Pos = iX_Count;

iY_Pos = iY_Count;


ucMap[iY_Count][iX_Count] = ' ';

continue;

}

ucMap[iY_Count][iX_Count] = ucStage_Map[uiStage][iY_Count][iX_Count];

}

}

return;

}



Load_Map을 통하여 복사한 맵을 리소스 파일에 있는 이미지를 통하여 실제 배경을 그린다.


LRESULT ON_PAINT(HWND hWnd, WPARAM wParam, LPARAM lParam) {

HDC Hdc;

PAINTSTRUCT ps;

int iX_Count, iY_Count;


Hdc = BeginPaint(hWnd, &ps);


// Background Drawing

for (iX_Count = 0; iX_Count < XFRAME; ++iX_Count) {

for (iY_Count = 0; iY_Count < YFRAME; ++iY_Count) {

if (ucMap[iY_Count][iX_Count] == '#') {

SelectObject(MemDC, HbmGround);

}

else if (ucMap[iY_Count][iX_Count] == ' ') {

SelectObject(MemDC, HbmRoad);

}

else if (ucMap[iY_Count][iX_Count] == '.') {

SelectObject(MemDC, HbmDot);

}

else if (ucMap[iY_Count][iX_Count] == 'B') {

SelectObject(MemDC, HbmBox);

}

BitBlt(Hdc, iX_Count*XTILE, iY_Count*YTILE, XTILE, YTILE, MemDC, 0, 0, SRCCOPY);

}

}


// Hero Drawing

SelectObject(MemDC, HbmHero);

BitBlt(Hdc, iX_Pos * XTILE, iY_Pos * YTILE, XTILE, YTILE, MemDC, 0, 0, SRCCOPY);


EndPaint(hWnd, &ps);


wsprintf(cTitle, L"STAGE : %d     KEY COUNT : %d", uiStage + 1, uiScore);

SetWindowText(hWnd, cTitle);


return 0;

}



방향키를 조작하여 캐릭터를 움직이고 캐릭터에 대한 움직임을 제어하는 함수

Home 키를 누르면 게임의 리셋이 작동하고 처음으로 돌아가게 된다.


LRESULT ON_KEYDOWN(HWND hWnd, WPARAM wParam, LPARAM lParam) {

int iX_Count, iY_Count;

int uiDot_Count;


ST_Area.left = iX_Pos * XTILE;

ST_Area.right = (iX_Pos + 1) * XTILE - 1;

ST_Area.top = iY_Pos * YTILE;

ST_Area.bottom = (iY_Pos + 1) * YTILE - 1;


// 키보드 방향키 입력에 따른 이동

switch (wParam) {

case VK_LEFT:

uiScore++;

HbmHero = HbmLeft;


// 통과가능 : 길, 점, 박스, 박스 + 점

// 길

if (ucMap[iY_Pos][iX_Pos - 1] == ' ') {

--iX_Pos;

ST_Area.left = iX_Pos * XTILE;

}

// 점

else if (ucMap[iY_Pos][iX_Pos - 1] == '.') {

--iX_Pos;

ST_Area.left = iX_Pos * XTILE;

}

// 박스

else if (ucMap[iY_Pos][iX_Pos - 1] == 'B') {

// 박스 + 길

if (ucMap[iY_Pos][iX_Pos - 2] == ' ') {

// Box Move

ucMap[iY_Pos][iX_Pos - 2] = ucMap[iY_Pos][iX_Pos - 1];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos][iX_Pos - 1] != '.') {

ucMap[iY_Pos][iX_Pos - 1] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos][iX_Pos - 1] = '.';

}

--iX_Pos;

ST_Area.left = (iX_Pos - 1) * XTILE;

}

// 박스 + 점

else if (ucMap[iY_Pos][iX_Pos - 2] == '.') {

// Box Move

ucMap[iY_Pos][iX_Pos - 2] = ucMap[iY_Pos][iX_Pos - 1];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos][iX_Pos - 1] != '.') {

ucMap[iY_Pos][iX_Pos - 1] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos][iX_Pos - 1] = '.';

}

--iX_Pos;

ST_Area.left = (iX_Pos - 1) * XTILE;

}

}

break;


case VK_RIGHT:

uiScore++;

// 이미지 복사

HbmHero = HbmRight;


// 통과가능 : 길, 점, 박스, 박스 + 점

// 길

if (ucMap[iY_Pos][iX_Pos + 1] == ' ') {

++iX_Pos;

ST_Area.right = (iX_Pos + 1) * XTILE;

}

// 점

else if (ucMap[iY_Pos][iX_Pos + 1] == '.') {

++iX_Pos;

ST_Area.right = (iX_Pos + 1) * XTILE;

}

// 박스

else if (ucMap[iY_Pos][iX_Pos + 1] == 'B') {

// 박스 + 길

if (ucMap[iY_Pos][iX_Pos + 2] == ' ') {

// Box Move

ucMap[iY_Pos][iX_Pos + 2] = ucMap[iY_Pos][iX_Pos + 1];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos][iX_Pos + 1] != '.') {

ucMap[iY_Pos][iX_Pos + 1] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos][iX_Pos + 1] = '.';

}

++iX_Pos;

ST_Area.right = (iX_Pos + 2) * XTILE;


}

// 박스 + 점

else if (ucMap[iY_Pos][iX_Pos + 2] == '.') {

// Box Move

ucMap[iY_Pos][iX_Pos + 2] = ucMap[iY_Pos][iX_Pos + 1];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos][iX_Pos + 1] != '.') {

ucMap[iY_Pos][iX_Pos + 1] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos][iX_Pos + 1] = '.';

}

++iX_Pos;

ST_Area.right = (iX_Pos + 2) * XTILE;

}

}

break;


case VK_UP:

uiScore++;

HbmHero = HbmBack;


// 통과가능 : 길, 점, 박스, 박스 + 점

// 길

if (ucMap[iY_Pos - 1][iX_Pos] == ' ') {

--iY_Pos;

ST_Area.top = iY_Pos * YTILE;

}

// 점

else if (ucMap[iY_Pos - 1][iX_Pos] == '.') {

--iY_Pos;

ST_Area.top = iY_Pos * YTILE;

}

// 박스

else if (ucMap[iY_Pos - 1][iX_Pos] == 'B') {

// 박스 + 길

if (ucMap[iY_Pos - 2][iX_Pos] == ' ') {

// Box Move

ucMap[iY_Pos - 2][iX_Pos] = ucMap[iY_Pos - 1][iX_Pos];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos - 1][iX_Pos] != '.') {

ucMap[iY_Pos - 1][iX_Pos] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos - 1][iX_Pos] = '.';

}

--iY_Pos;

ST_Area.top = (iY_Pos - 1) * YTILE;

}

// 박스 + 점

else if (ucMap[iY_Pos - 2][iX_Pos] == '.') {

// Box Move

ucMap[iY_Pos - 2][iX_Pos] = ucMap[iY_Pos - 1][iX_Pos];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos - 1][iX_Pos] != '.') {

ucMap[iY_Pos - 1][iX_Pos] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos - 1][iX_Pos] = '.';

}

--iY_Pos;

ST_Area.top = (iY_Pos - 1) * YTILE;

}

}

break;


case VK_DOWN:

uiScore++;

HbmHero = HbmFront;


// 길

if (ucMap[iY_Pos + 1][iX_Pos] == ' ') {

++iY_Pos;

ST_Area.bottom = (iY_Pos + 1) * YTILE;

}

// 점

else if (ucMap[iY_Pos + 1][iX_Pos] == '.') {

++iY_Pos;

ST_Area.bottom = (iY_Pos + 1) * YTILE;

}

// 박스

else if (ucMap[iY_Pos + 1][iX_Pos] == 'B') {

// 박스 + 길

if (ucMap[iY_Pos + 2][iX_Pos] == ' ') {

// Box Move

ucMap[iY_Pos + 2][iX_Pos] = ucMap[iY_Pos + 1][iX_Pos];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos + 1][iX_Pos] != '.') {

ucMap[iY_Pos + 1][iX_Pos] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos + 1][iX_Pos] = '.';

}

++iY_Pos;

ST_Area.bottom = (iY_Pos + 2) * YTILE;

}

// 박스 + 점

else if (ucMap[iY_Pos + 2][iX_Pos] == '.') {

// Box Move

ucMap[iY_Pos + 2][iX_Pos] = ucMap[iY_Pos + 1][iX_Pos];

// 다시 길 그리기

if (ucStage_Map[uiStage][iY_Pos + 1][iX_Pos] != '.') {

ucMap[iY_Pos + 1][iX_Pos] = ' ';

}

// 다시 점 그리기

else {

ucMap[iY_Pos + 1][iX_Pos] = '.';

}

++iY_Pos;

ST_Area.bottom = (iY_Pos + 2) * YTILE;

}

}

break;


case VK_HOME:

Message_Ret = MessageBox(hWnd, L"게임을 재시작 하시겠습니까?", L"Game Restart", MB_YESNO);


if (Message_Ret == IDYES) {

Load_Map();

InvalidateRect(hWnd, NULL, TRUE);

}

return 0;

}


InvalidateRect(hWnd, &ST_Area, FALSE);


uiDot_Count = 0;

for (iX_Count = 0; iX_Count < XFRAME; iX_Count++) {

for (iY_Count = 0; iY_Count < YFRAME; iY_Count++) {

if (ucMap[iY_Count][iX_Count] == 'B') {

if (ucStage_Map[uiStage][iY_Count][iX_Count] == '.') {

++uiDot_Count;

}

}

}

}


if (uiDot_Count == uiDot_Num) {

MessageBox(hWnd, L"Stage Clear", L"Clear", MB_OK);

uiStage++;


if (uiScore >= STAGE) {

MessageBox(hWnd, L"End Game", L"End", MB_OK);

SendMessage(hWnd, WM_DESTROY, 0, 0);

}

Load_Map();

InvalidateRect(hWnd, NULL, TRUE);

}


return 0;

}








728x90