#include <windows.h>
#include "smart.h"
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass = "Push Push";
LRESULT OnDestroy(HWND, WPARAM, LPARAM);
LRESULT OnCreate(HWND, WPARAM, LPARAM);
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
LRESULT OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
void LoadMap();
//메세지맵에서 자주쓰는 함수를 위에 위치하는게 좋다(자주쓰는게 뒤에 있으면 while이 자주 도니까)
stMsgMap MsgMap[] = {
{ WM_PAINT, OnPaint },
{ WM_KEYDOWN, OnKeyDown },
{ WM_CREATE, OnCreate },
{ WM_DESTROY, OnDestroy },
{ WM_NULL, 0 },
};
//캐릭터와 지도를 저장할 HBITMAP 전역 변수
static HBITMAP HbmHero;
static HBITMAP HbmFront;
static HBITMAP HbmLeft;
static HBITMAP HbmRight;
static HBITMAP HbmBack;
static HBITMAP HbmGround;
static HBITMAP HbmRoad;
static HBITMAP HbmBox;
static HBITMAP HbmDot;
static HDC MemDC;
//지도의 점을 count할 변수(종료조건)
UINT uiDotNum;
//현재 stage를 가질 변수
UINT uiStage=0;
//이동횟수를 저장할 변수(점수)
UINT uiScore;
WCHAR cTile[200];
//지도 정보를 매핑해서 들고있는 3차원 배열
UCHAR ucStageMap[STAGE][Y_FRAME][X_FRAME + 1] = {
{ "###############"
, "#@ #"
, "# . B #"
, "# B . #"
, "# B #"
, "# ## ## #"
, "# . #"
, "# ## ###### #"
, "# #"
, "###############"
}
,
{ "###############"
, "#@ # #"
, "# ##### # # #"
, "# # # #"
, "# ## ## . #"
, "# ## ####### #"
, "# #"
, "# ## # # # ## #"
, "# #"
, "###############"
}
};
//하나의 스테이지 정보를 가지고 있을 2차원 배열
UCHAR ucMap[Y_FRAME][X_FRAME + 1];
//Hero의 위치 정보를 추적하는 변수
int ixPos = 0;
int iyPos = 0;
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);
hWnd = CreateWindow(lpszClass, lpszClass, WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, X_WINSIZE, Y_WINSIZE,
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;
//message map 기법을 통해서 switch case 문을 지우고 while문이 모든 함수를 처리한다.
while (WM_NULL != (*stpMap).uiMsg)
{
if (iMessage == (*stpMap).uiMsg)
{
//내부적으로 처리하기 때문에 와일문이 돌면 안되기 때문에 return으로 처리한다.
return (((*stpMap).fp)(hWnd, wParam, lParam));
}
++stpMap;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
DeleteObject(HbmFront);
DeleteObject(HbmLeft);
DeleteObject(HbmRight);
DeleteObject(HbmBack);
DeleteObject(HbmGround);
DeleteObject(HbmRoad);
DeleteObject(HbmDot);
DeleteObject(HbmBox);
DeleteDC(MemDC);
PostQuitMessage(0);
return 0;
}
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
hdc = GetDC(hWnd);
MemDC = CreateCompatibleDC(hdc);
HbmFront = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP3));
HbmLeft = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP4));
HbmRight = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP5));
HbmBack = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP2));
HbmGround = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
HbmRoad = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP6));
HbmDot = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP7));
HbmBox = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP9));
ReleaseDC(hWnd, hdc);
HbmHero = HbmFront;
LoadMap();
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
int iCntx;
int iCnty;
hdc = BeginPaint(hWnd, &ps);
//maping된 구조체의 정보를 가지고와 지도를 그려주는 for문
for (iCnty = 0; iCnty<10; iCnty++)
{
for (iCntx = 0; iCntx<15; iCntx++)
{
if ('#' == ucMap[iCnty][iCntx])
{
SelectObject(MemDC, HbmGround);
}
else if (' ' == ucMap[iCnty][iCntx])
{
SelectObject(MemDC, HbmRoad);
}
else if ('.' == ucMap[iCnty][iCntx])
{
SelectObject(MemDC, HbmDot);
}
else if ('B' == ucMap[iCnty][iCntx])
{
SelectObject(MemDC, HbmBox);
}
BitBlt(hdc, iCntx*X_TILE,iCnty*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);
EndPaint(hWnd, &ps);
//점수와 stage를 프로그램 상단에 찍어준다.
wsprintf(cTile, "Stage : %d KeyCount: %d", uiStage + 1, uiScore);
SetWindowText(hWnd, cTile);
return 0;
}
LRESULT OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
UINT uixCnt;
UINT uiyCnt;
UINT uiDotCnt;
RECT stArea;
int iRet;
//hero가 이동할때 hero가 이동한 자리와 이동하기 전만 다시 그려주기 위해서
//현재 hero의 이미지를 저장하기 위한 구조체
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_RIGHT:
HbmHero = HbmRight;
//hero가 이동할수 있는곳만 이동하도록 하는 if문
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 ('B' == ucMap[iyPos][ixPos + 1])
{
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;
}
}
++uiScore;
break;
case VK_LEFT:
HbmHero = HbmLeft;
if (' ' == ucMap[iyPos][ixPos - 1])
{
--ixPos;
stArea.left = (ixPos-1) * X_TILE;
}
else if ('.' == ucMap[iyPos][ixPos - 1])
{
--ixPos;
stArea.left = (ixPos-1) * X_TILE;
}
else if ('B' == ucMap[iyPos][ixPos - 1])
{
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-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.left = (ixPos- 2) * X_TILE;
}
}
++uiScore;
break;
case VK_UP:
HbmHero = HbmBack;
if (' ' == ucMap[iyPos-1][ixPos])
{
--iyPos;
stArea.top = (iyPos - 1) * Y_TILE;
}
else if ('.' == ucMap[iyPos-1][ixPos])
{
--iyPos;
stArea.top = (iyPos - 1) * Y_TILE;
}
else if ('B' == ucMap[iyPos-1][ixPos])
{
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 - 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.top = (iyPos - 2) * Y_TILE;
}
}
++uiScore;
break;
case VK_DOWN:
HbmHero = HbmFront;
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 ('B' == ucMap[iyPos + 1][ixPos])
{
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;
}
}
++uiScore;
break;
case VK_HOME:
iRet = MessageBox(hWnd, "다시 하시겠습니까?", "알림", MB_YESNOCANCEL);
if (IDYES == iRet)
{
LoadMap();
InvalidateRect(hWnd, NULL, TRUE);
}
return 0;
}
InvalidateRect(hWnd, &stArea, FALSE);
uiDotCnt = 0;
for (uiyCnt = 0; uiyCnt<Y_FRAME; ++uiyCnt)
{
for (uixCnt = 0; uixCnt<X_FRAME; ++uixCnt)
{
if (ucMap[uiyCnt][uixCnt] == 'B')
{
if (ucStageMap[uiStage][uiyCnt][uixCnt] == '.')
{
++uiDotCnt;
}
}
}
}
if (uiDotCnt == uiDotNum)
{
MessageBox(hWnd, "클리어!", "알림", MB_OK);
if (uiStage >= STAGE)
{
MessageBox(hWnd, "게임이 끝났습니다.", "알림", MB_OK);
SendMessage(hWnd, WM_DESTROY,0,0);
return 0;
}
++uiStage;
LoadMap();
InvalidateRect(hWnd, NULL, TRUE);
return 0;
}
return 0;
}
//판마다 맵을 불러올
void LoadMap()
{
int iCntx;
int iCnty;
uiDotNum = 0;
uiScore = 0;
//memcopy가 아니고 for문을 돌리는 이유는 hero가 어디있는지 찾아서 rode로 바꿔주기 위해서
for (iCnty = 0; iCnty<10; iCnty++)
{
for (iCntx = 0; iCntx<15; iCntx++)
{
//지도안의 dot의 갯수를 샌다.
if ('.' == ucStageMap[uiStage][iCnty][iCntx])
{
++uiDotNum;
}
if ('@' == ucStageMap[uiStage][iCnty][iCntx])
{
//@는 Hero의 초기 위치만 잡아주고 필요없기 때문에 rode로 대체한다.
ixPos = iCntx;
iyPos = iCnty;
ucMap[iCnty][iCntx] = ' ';
continue;
}
ucMap[iCnty][iCntx]=ucStageMap[uiStage][iCnty][iCntx];
}
}
return;
}
조금씩 정리되는데로 추가하기
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151120-김재홍-win32API-7일차 (2) | 2015.11.20 |
---|---|
20151120_박서연_일일업무일지_API(7) (4) | 2015.11.20 |
20151120 업무일지 -여지윤- Win32 API 7 (4) | 2015.11.20 |
20151120 - 권오민 - WinAPI 7일차 (4) | 2015.11.20 |
20151118 - WinAPI 일지 엄민웅 (게임 만들기 경우의 수 생각하기) (작성중) (5) | 2015.11.20 |
20151119 임현수 업무일지 WIN32API #6 게임 푸시푸시 구현 (4) | 2015.11.20 |
20151119_안향진_API_6 (5) | 2015.11.20 |
20151119 / API_6-푸시푸시 끝/ 남수진 (4) | 2015.11.20 |