#include <windows.h> #include "resource.h" #include "Smart.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE g_hInst; LPSTR lpszClass = L"PushPushGame";
LRESULT On_Destroy(HWND, WPARAM, LPARAM); LRESULT On_Create(HWND hWnd, WPARAM wParam, LPARAM lParam); LRESULT On_Paint(HWND hWnd, WPARAM wParam, LPARAM lParam); LRESULT On_KeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam); void LoadMap(); StMsgMap msgMap[] = { { WM_DESTROY, On_Destroy }, { WM_CREATE, On_Create }, { WM_PAINT, On_Paint }, { WM_KEYDOWN, On_KeyDown }, { WM_NULL, 0 } };
static HBITMAP hbmFront; static HBITMAP hbmBack; static HBITMAP hbmLeft; static HBITMAP hbmRight;
static HBITMAP hbmGround; static HBITMAP hbmRoad; static HBITMAP hbmHero; static HBITMAP hbmBox; static HBITMAP hbmDot;
HDC memDC;
/*현재 히어로의 위치 -> '@'*/ static int iXPos; static int iYPos;
unsigned int uiStage; //현재 몇판인지 기억.
unsigned int uiDotNum; //현재 맵에 unsigned int uiDotCount;
unsigned int uiScore;
WCHAR cTitle[200]; //스테이지 UCHAR ucStageMap[STAGE][Y_FRAME][X_FRAME + 1] = { { { "###############" }, { "###############" }, { "### ###" }, { "### B ###" }, { "### . ###" }, { "### . B ###" }, { "### . B ###" }, { "### @ ###" }, { "###############" }, { "###############" }, }, { { "###############" }, { "###############" }, { "###### ######" }, { "#### . ####" }, { "### ## ###" }, { "### ## B ###" }, { "#### ###" }, { "####@ ######" }, { "###############" }, { "###############" }, }, }; //실제 맵 UCHAR ucMap[Y_FRAME][X_FRAME + 1];
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst = hInstance;
WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = (WNDPROC)WndProc; WndClass.lpszClassName = lpszClass; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&WndClass); //X_WIN_SIZE, Y_WIN_SIZE 로 창이 어디에 뜨는지 설정. hWnd = CreateWindow ( lpszClass, // 윈도우의 클래스를 지정하는 문자열 lpszClass, // 윈도우의 타이틀 바 이름 WS_OVERLAPPEDWINDOW, // 윈도우의 형태를 지정, WS_OVERLAPPEDWINDOW 은 가장 무난한 형태의 윈도우 설정 상태 CW_USEDEFAULT, // 윈도우의 크기와 위치를 지정, x, CW_USEDEFAULT 은 적당한 크기와 위치를 설정, 차일드 윈도우는 부모 윈도우의 좌상단을 기준 CW_USEDEFAULT, // y X_WIN_SIZE, // 차일드 윈도우의 창 크기 설정, x Y_WIN_SIZE, // y NULL, (HMENU)NULL, hInstance, NULL // 이건 나중에.. ); ShowWindow(hWnd, nCmdShow);
while (GetMessage(&Message, 0, 0, 0)) { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { StMsgMap *stpMap = msgMap;
/*asm 때 했던 방식 그대로 활용, switch-case 를 함수포인터로 표현. - 이렇게 한다면 공유하는 변수들을 전역에 가지고 있어야 한다.*/ while ((*stpMap).uiMsg != WM_NULL) { if (iMessage == (*stpMap).uiMsg) { ((*stpMap).fp)(hWnd, wParam, lParam);
return 0; }
++stpMap; }
/* switch (iMessage) { case WM_CREATE: hbmFront = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_FRONT)); hbmBack = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_BACK)); hbmLeft = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_LEFT)); hbmRight = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_RIGHT)); hbmGround = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND)); return 0;
case WM_DESTROY: DeleteObject(hbmFront); DeleteObject(hbmBack); DeleteObject(hbmLeft); DeleteObject(hbmRight); DeleteObject(hbmGround); PostQuitMessage(0); return 0; } */
return(DefWindowProc(hWnd, iMessage, wParam, lParam)); }
LRESULT On_Destroy(HWND hWnd, WPARAM wParam, LPARAM lParam) { DeleteObject(hbmFront); DeleteObject(hbmBack); DeleteObject(hbmLeft); DeleteObject(hbmRight); DeleteObject(hbmGround); DeleteObject(hbmRoad); DeleteObject(hbmDot); DeleteObject(hbmBox); DeleteDC(memDC); PostQuitMessage(0); return 0; }
LRESULT On_Create(HWND hWnd, WPARAM wParam, LPARAM lParam) { HDC hdc;
hdc = GetDC(hWnd); memDC = CreateCompatibleDC(hdc);
hbmFront = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_FRONT)); hbmBack = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_BACK)); hbmLeft = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_LEFT)); hbmRight = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_CHAR_RIGHT)); hbmGround = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND)); hbmRoad = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_ROAD)); hbmDot = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_DOT)); hbmBox = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP_BOX));
LoadMap();
ReleaseDC(hWnd, hdc);
hbmHero = hbmFront;
return 0; }
LRESULT On_Paint(HWND hWnd, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int iXCnt; int iYCnt;
/*맵 그리기*/ hdc = BeginPaint(hWnd, &ps); for (iYCnt = 0; iYCnt < Y_FRAME; ++iYCnt) { for (iXCnt = 0; iXCnt < X_FRAME; ++iXCnt) { switch (ucMap[iYCnt][iXCnt]) { case '#': SelectObject(memDC, hbmGround); break;
case ' ': SelectObject(memDC, hbmRoad); break;
case '.': SelectObject(memDC, hbmDot); break;
case 'B': SelectObject(memDC, hbmBox); break; } BitBlt(hdc, (iXCnt * X_TILE), (iYCnt * Y_TILE), X_TILE, Y_TILE, memDC, 0, 0, SRCCOPY); } }
SelectObject(memDC, hbmHero); BitBlt(hdc, (iXPos * X_TILE), (iYPos * Y_TILE), X_TILE, Y_TILE, memDC, 0, 0, SRCCOPY);
wsprintf(cTitle, L"STAGE : %d KEYCOUNT : %d", uiStage + 1, uiScore); SetWindowText(hWnd, cTitle); EndPaint(hWnd, &ps); return 0; }
LRESULT On_KeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam) { int iXCnt; int iYCnt; RECT stArea; int iRet;
stArea.left = (iXPos * X_TILE); stArea.right = ((iXPos + 1) * X_TILE); stArea.top = (iYPos * Y_TILE); stArea.bottom = ((iYPos + 1) * Y_TILE);
switch (wParam) { case VK_LEFT: hbmHero = hbmLeft; ++uiScore; if (ucMap[iYPos][iXPos - 1] == ' ')//이제 이동 시킬 조건이 여기 다 들어간다., 일단 길이면 { --iXPos; stArea.left = (iXPos * X_TILE); } else if (ucMap[iYPos][iXPos - 1] == '.')//닷 이면 { --iXPos; stArea.left = (iXPos * X_TILE); } else if (ucMap[iYPos][iXPos - 1] == 'B')//상자이고, { if (ucMap[iYPos][iXPos - 2] == ' ')//길 이면 { ucMap[iYPos][iXPos - 2] = ucMap[iYPos][iXPos - 1]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos][iXPos - 1] != '.') { ucMap[iYPos][iXPos - 1] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos][iXPos - 1] = '.'; }//점 아니면 길밖에 없다 --iXPos; stArea.left = ((iXPos - 1) * X_TILE); } else if (ucMap[iYPos][iXPos - 2] == '.')//닷 이면 { ucMap[iYPos][iXPos - 2] = ucMap[iYPos][iXPos - 1]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos][iXPos - 1] != '.') { ucMap[iYPos][iXPos - 1] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos][iXPos - 1] = '.'; }//점 아니면 길밖에 없다 --iXPos; stArea.left = ((iXPos - 1) * X_TILE); } } //ucMap[iYPos][iXPos] = ucStageMap[uiStage][iYPos][iXPos]; //ucMap[iYPos][iXPos] = '@'; break;
case VK_RIGHT: hbmHero = hbmRight; ++uiScore;
if (ucMap[iYPos][iXPos + 1] == ' ')//이제 이동 시킬 조건이 여기 다 들어간다., 일단 길이면 { ++iXPos; stArea.right = ((iXPos + 1) * X_TILE); } else if (ucMap[iYPos][iXPos + 1] == '.')//닷 이면 { ++iXPos; stArea.right = ((iXPos + 1) * X_TILE); } else if (ucMap[iYPos][iXPos + 1] == 'B')//상자이고, { if (ucMap[iYPos][iXPos + 2] == ' ')//길 이면 { ucMap[iYPos][iXPos + 2] = ucMap[iYPos][iXPos + 1]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos][iXPos + 1] != '.') { ucMap[iYPos][iXPos + 1] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos][iXPos + 1] = '.'; }//점 아니면 길밖에 없다 ++iXPos; stArea.right = ((iXPos + 2) * X_TILE); } else if (ucMap[iYPos][iXPos + 2] == '.')//닷 이면 { ucMap[iYPos][iXPos + 2] = ucMap[iYPos][iXPos + 1]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos][iXPos + 1] != '.') { ucMap[iYPos][iXPos + 1] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos][iXPos + 1] = '.'; }//점 아니면 길밖에 없다 ++iXPos; stArea.right = ((iXPos + 2) * X_TILE); } }
//ucMap[iYPos][iXPos] = ucStageMap[uiStage][iYPos][iXPos]; //ucMap[iYPos][iXPos] = '@'; break;
case VK_UP: hbmHero = hbmBack; ++uiScore; if (ucMap[iYPos - 1][iXPos] == ' ')//이제 이동 시킬 조건이 여기 다 들어간다., 일단 길이면 { --iYPos; stArea.top = (iYPos * Y_TILE); } else if (ucMap[iYPos - 1][iXPos] == '.')//닷 이면 { --iYPos; stArea.top = (iYPos * Y_TILE); } else if (ucMap[iYPos - 1][iXPos] == 'B')//상자이고, { if (ucMap[iYPos - 2][iXPos] == ' ')//길 이면 { ucMap[iYPos - 2][iXPos] = ucMap[iYPos - 1][iXPos]; if (ucStageMap[uiStage][iYPos - 1][iXPos] != '.') { ucMap[iYPos - 1][iXPos] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos - 1][iXPos] = '.'; }//점 아니면 길밖에 없다 --iYPos; stArea.top = ((iYPos - 1) * Y_TILE); } else if (ucMap[iYPos - 2][iXPos] == '.')//닷 이면 { ucMap[iYPos - 2][iXPos] = ucMap[iYPos - 1][iXPos]; if (ucStageMap[uiStage][iYPos - 1][iXPos] != '.') { ucMap[iYPos - 1][iXPos] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos - 1][iXPos] = '.'; }//점 아니면 길밖에 없다 --iYPos; stArea.top = ((iYPos - 1) * Y_TILE); } } //ucMap[iYPos][iXPos] = ucStageMap[uiStage][iYPos][iXPos]; //ucMap[iYPos][iXPos] = '@'; break;
case VK_DOWN: hbmHero = hbmFront; ++uiScore; if (ucMap[iYPos + 1][iXPos] == ' ')//이제 이동 시킬 조건이 여기 다 들어간다., 일단 길이면 { ++iYPos; stArea.bottom = ((iYPos + 1) * Y_TILE); } else if (ucMap[iYPos + 1][iXPos] == '.')//닷 이면 { ++iYPos; stArea.bottom = ((iYPos + 1) * Y_TILE); } else if (ucMap[iYPos + 1][iXPos] == 'B')//상자이고, { if (ucMap[iYPos + 2][iXPos] == ' ')//길 이면 { ucMap[iYPos + 2][iXPos] = ucMap[iYPos + 1][iXPos]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos + 1][iXPos] != '.') { ucMap[iYPos + 1][iXPos] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos + 1][iXPos] = '.'; }//점 아니면 길밖에 없다 ++iYPos; stArea.bottom = ((iYPos + 2) * Y_TILE); } else if (ucMap[iYPos + 2][iXPos] == '.')//닷 이면 { ucMap[iYPos + 2][iXPos] = ucMap[iYPos + 1][iXPos]; //박스 거기로 옮기고 if (ucStageMap[uiStage][iYPos + 1][iXPos] != '.') { ucMap[iYPos + 1][iXPos] = ' '; //그 부분을 길로 만든다. 이 부분이 잘못됬으므로 고치자. } else { ucMap[iYPos + 1][iXPos] = '.'; }//점 아니면 길밖에 없다 ++iYPos; stArea.bottom = ((iYPos + 2) * Y_TILE); } } //ucMap[iYPos][iXPos] = ucStageMap[uiStage][iYPos][iXPos]; //ucMap[iYPos][iXPos] = '@'; break;
case VK_HOME: iRet = MessageBox(hWnd, L"다시 시작 하겠습니까?", L"Button", MB_YESNO); if (iRet == IDYES) { InvalidateRect(hWnd, NULL, TRUE); LoadMap(); } return 0; }
InvalidateRect(hWnd, &stArea, FALSE);
uiDotCount = 0; for (iYCnt = 0; iYCnt < Y_FRAME; ++iYCnt) { for (iXCnt = 0; iXCnt < X_FRAME; ++iXCnt) { if (ucMap[iYCnt][iXCnt] == 'B') { if (ucStageMap[uiStage][iYCnt][iXCnt] == '.') // 두개가 일치한다면 { ++uiDotCount; } } }
if (uiDotCount == uiDotNum) { MessageBox(hWnd, TEXT("클리어 하셨습니다."), TEXT("Button"), MB_OK); break; } }
return 0; } //맵 로드 void LoadMap() { int iXCnt; int iYCnt;
uiDotNum = 0; uiScore = 0;
//맴 카피를 쓰지 않고 이중 포문을 사용하는 이유는 골뱅이의 위치 때문이다. //즉, 골뱅이의 좌표를 알 수 있도록 맴카피를 쓰지 않고 맵을 로드하며 직접 @의 위치를 찾는 것이다. for (iYCnt = 0; iYCnt < Y_FRAME; ++iYCnt) { for (iXCnt = 0; iXCnt < X_FRAME; ++iXCnt) { if (ucStageMap[uiStage][iYCnt][iXCnt] == '.') { ++uiDotNum; }
if (ucStageMap[uiStage][iYCnt][iXCnt] == '@') { iYPos = iYCnt; iXPos = iXCnt;//현재 좌표 값에 넣는다. ucMap[iYCnt][iXCnt] == ' '; continue; } ucMap[iYCnt][iXCnt] = ucStageMap[uiStage][iYCnt][iXCnt]; } }
return; } |