C语言图形化推箱子完整代码

写了三关带界面的推箱子

开发环境:Visual Studio2013

运行环境:Visual Studio2013-2022

以下为详细代码:

// TUITUI.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "TUITUI.h"
#include "atlstr.h"
#include <string.h>

#define MAX_LOADSTRING 100
#define WINDOW_WIDTH	800 //为窗口宽度定义的宏,以方便在此处修改窗口宽度
#define WINDOW_HEIGHT	800 //为窗口高度定义的宏,以方便在此处修改窗口高度
// 全局变量: 
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

// 此代码模块中包含的函数的前向声明: 
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO:  在此放置代码。
	MSG msg;
	HACCEL hAccelTable;

	// 初始化全局字符串
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TUITUI, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// 执行应用程序初始化: 
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TUITUI));

	// 主消息循环: 
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  函数:  MyRegisterClass()
//
//  目的:  注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TUITUI));//图标*.rc查看代码打开
	wcex.hCursor        = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));//光标
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);//背景
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_TUITUI);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   函数:  InitInstance(HINSTANCE, int)
//
//   目的:  保存实例句柄并创建主窗口
//
//   注释: 
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;
   hInst = hInstance; // 将实例句柄存储在全局变量中
   //获取屏幕分辨率(GetSystemMetrics(SM_CXSCREEN) - 800) / 2, (GetSystemMetrics(SM_CYSCREEN) - 800) / 2
   int width = GetSystemMetrics(0);
   int height = GetSystemMetrics(1);

   //3. WS_POPUP,//WS_POPUP弹出式无边框窗口
   hWnd = CreateWindow(szWindowClass, _T("推箱子小游戏"), WS_POPUP,
	   (width - 800) / 2, (height - 800) / 2, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);//窗口位置居中和大小固定↑

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   HDC hdc = GetDC(hWnd);
   return TRUE;
}

//
//  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//

int Map[3][11][11] = {
		{
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 1, 1, 1, 0, 2, 0, 1, 1, 1, 1 },
			{ 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
			{ 1, 1, 0, 3, 1, 0, 0, 3, 3, 0, 1 },
			{ 1, 1, 0, 3, 0, 3, 1, 3, 0, 0, 1 },
			{ 1, 1, 1, 1, 3, 5, 5, 5, 1, 1, 1 },
			{ 1, 1, 1, 1, 0, 5, 5, 5, 5, 1, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
		},
		{
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1 },
			{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 3, 0, 1, 1, 5, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
			{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
			{ 1, 5, 0, 0, 1, 0, 0, 3, 0, 0, 1 },
			{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 5, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
		},
		{
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
			{ 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 1, 0, 0, 5, 0, 0, 0, 1 },
			{ 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1 },
			{ 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 3, 0, 0, 5, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
			{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1 },
			{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
		}
};

HWND hWnd;
HDC hdc;
bool Init(HWND);//初始化
void MouseMove(HWND, int, int, WPARAM);//鼠标位置
void MouseClick(HWND, int, int, WPARAM);//鼠标点击
void DrawFace(HDC);//游戏入口
void TextFace(HDC);//标题、注释文字和×
void DrawMap(HDC);//绘制地图
void PlayGame(WPARAM);//移动
void MapChange();//切换地图
void nextMap(HDC);//进入下一个地图
bool CleanUp(HWND);//删除画板

bool isClose = true;//×和√的切换
bool isStart = true;//游戏开始
bool isBegin = true;//进入游戏
bool textc = false;//显示关卡数

bool win = false;//庆祝成功
bool mapNumWait = true;//等待进入下一关
int mapNumGoing = 1;//第几关
int mapNumGoingC = 1;//第几关_副本
bool nextm = true;//下一个地图
int box = 0;//成功个数
bool final = false;//结局

int GameMap[11][11];//游戏地图
int RecantMap[11][11];//临时地图(用于撤销)
int TempMap[11][11];//临时地图(用于重玩)
int PosX1=0, PosY1=0;//临时坐标
int PosX, PosY;//人的坐标
int steps = 0;//步数

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	
	switch (message)
	{
	case WM_LBUTTONDOWN:
		MouseClick(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
		break;
	case WM_MOUSEMOVE:
		MouseMove(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
		break;
	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)    // 如果被按下的键是ESC
			DestroyWindow(hWnd);// 销毁窗口, 并发送一条WM_DESTROY消息
		PlayGame(wParam);
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		break;
	case WM_PAINT:
		PAINTSTRUCT ps;
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		textc = true;
		Init(hWnd);
		EndPaint(hWnd, &ps);			//EndPaint函数标记指定窗口的绘画过程结束
		ValidateRect(hWnd, NULL);		// 更新客户区的显示		
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
//初始化
bool Init(HWND hWnd){
	
	hdc = GetDC(hWnd);//绘制界面
	DrawFace(hdc);
	return true;
}
//游戏入口
void DrawFace(HDC hdc){
	if (isBegin){
	HBRUSH hbrush1 = CreateSolidBrush(RGB(180, 220, 230));//草绿色162, 196, 149
	HFONT hFont1 = CreateFont(100, 0, 0, 0, FW_HEAVY, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, _T("微软雅黑"));
	HFONT hFont2 = CreateFont(35, 0, 0, 0, FW_HEAVY, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, _T("微软雅黑"));
	SelectObject(hdc,hbrush1);
	Rectangle(hdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
	SelectObject(hdc, hFont1);  //将字体选入设备环境中
	SetBkMode(hdc, TRANSPARENT);    //设置输出文字背景色为透明
	SetTextColor(hdc, RGB(50, 50, 200));
	TextOut(hdc, WINDOW_WIDTH / 2 -300,WINDOW_HEIGHT/2-200 , _T("推箱子!"), strlen("推箱子!"));
	
	if (isStart){
		SetTextColor(hdc, RGB(150, 150, 150));
		TextOut(hdc, WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2 , _T("Start"), strlen("Start"));
	}
	else if (!isStart){
		SetTextColor(hdc, RGB(50, 50, 200));
		TextOut(hdc, WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2, _T("Start"), strlen("Start"));
	}
	
	SelectObject(hdc, hFont2);  //将字体选入设备环境中
	SetBkMode(hdc, TRANSPARENT);    //设置输出文字背景色为透明
	SetTextColor(hdc, RGB(50, 50, 200));
	TextOut(hdc, WINDOW_WIDTH/2 - 100, WINDOW_HEIGHT - 100, _T("作者:谢雨虹"), lstrlen(_T("作者:谢雨虹")));
	
	
	DeleteObject(hbrush1);
	DeleteObject(hFont1);//释放字体对象
	DeleteObject(hFont2);//释放字体对象
	}
	else if (!isBegin){
		InvalidateRect(hWnd, NULL, TRUE);	//重绘
		MapChange();
		DrawMap(hdc);
		TextFace(hdc);
		
	}
	
}
//标题、注释文字、关卡数、结算和×
void TextFace(HDC hdc)
{
	HBRUSH hBrush, hBrush1, hBrush2, hBrush3, hBrush4;
	hBrush = CreateSolidBrush(RGB(150, 150, 150));
	hBrush1 = CreateSolidBrush(RGB(180, 220, 230));
	hBrush2 = CreateSolidBrush(RGB(100, 0, 100));
	hBrush3 = CreateSolidBrush(RGB(50, 100, 120));
	hBrush4 = CreateSolidBrush(RGB(255, 150, 150));
	HFONT hFont1 = CreateFont(35, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, _T("微软雅黑"));
	HFONT hFont2 = CreateFont(100, 0, 0, 0, FW_HEAVY, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, _T("微软雅黑"));
	SelectObject(hdc, hFont1);  //将字体选入设备环境中
	SetBkMode(hdc, TRANSPARENT);    //设置输出文字背景色为透明
	SetTextColor(hdc,RGB(50,50,200));
	_TCHAR c1[] = _T("操作提示:");
	_TCHAR c2[] = _T("                   W              ↑");
	_TCHAR c3[] = _T("      按键   A  S  D  或←  ↓  →移动箱子。");
	_TCHAR c4[] = _T("      按下“C”键,撤销上一步。");
	_TCHAR c5[] = _T("      按下“P”键,重新开始当前关。");

	TextOut(hdc, 4 + 12, 550 , c1, lstrlen(c1));
	TextOut(hdc, 4 + 12, 550 + 35, c2, lstrlen(c2));
	TextOut(hdc, 4 + 12, 550 + 70, c3, lstrlen(c3));
	TextOut(hdc, 4 + 12, 550 + 110, c4, lstrlen(c4));
	TextOut(hdc, 4 + 12, 550 + 150, c5, lstrlen(c5));
	
	_TCHAR d1[] = _T("关卡:第一关");
	_TCHAR d2[] = _T("关卡:第二关");
	_TCHAR d3[] = _T("关卡:第三关");
	_TCHAR d4[] = _T("墙壁");
	_TCHAR d5[] = _T("玩家");
	_TCHAR d6[] = _T("箱子");
	_TCHAR d7[] = _T("成功点");
	_TCHAR d8[] = _T("人在成功点");
	_TCHAR d9[] = _T("箱子推到成功点");
	CString str;
	str.Format(_T("步数: %d "), steps);
	TextOut(hdc, 550 + 10, 24 + 90, str, lstrlen(str));
	//图例
	HRGN hrgn;//画圆
	//墙壁
	SelectObject(hdc, hBrush1);
	Rectangle(hdc, 550 + 10, 170, 600, 210);
	TextOut(hdc, 600 + 10, 175, d4, lstrlen(d4));
	//玩家
	hrgn = CreateEllipticRgn(550+10, 230, 600, 270);
	FillRgn(hdc, hrgn, hBrush2);
	TextOut(hdc, 600 + 10, 235, d5, lstrlen(d5));
	//箱子
	SelectObject(hdc, hBrush3);
	Rectangle(hdc, 550 + 10, 290, 600, 330);
	TextOut(hdc, 600 + 10, 295, d6, lstrlen(d6));
	//成功点
	SelectObject(hdc, hBrush);
	Rectangle(hdc, 550 + 10, 350, 600, 390);
	TextOut(hdc, 600 + 10, 355, d7, lstrlen(d7));
	//人在成功点
	SelectObject(hdc, hBrush);
	Rectangle(hdc, 550 + 10, 410, 600, 450);
	hrgn = CreateEllipticRgn(550 + 10, 410, 600, 450);
	FillRgn(hdc, hrgn, hBrush2);
	TextOut(hdc, 600 + 10, 415, d8, lstrlen(d8));
	//箱子在成功点
	SelectObject(hdc, hBrush4);
	Rectangle(hdc, 550 + 10, 470, 600, 510);
	TextOut(hdc, 600 + 10, 475, d9, lstrlen(d9));
	if (textc)
	{
		switch (mapNumGoing)
		{
		case 1:
			TextOut(hdc, 550 + 10, 24 + 30, d1, lstrlen(d1));
			break;
		case 2:
			TextOut(hdc, 550 + 10, 24 + 30, d2, lstrlen(d2));
			break;
		case 3:
			TextOut(hdc, 550 + 10, 24 + 30, d3, lstrlen(d3));
			break;
		}
		textc = false;
	}
	if (isClose)
	{
		SetTextColor(hdc, RGB(255, 255, 255));
		TextOut(hdc, WINDOW_WIDTH - 40, 2, _T("O"), strlen("O"));
		SetTextColor(hdc, RGB(50, 50, 200));
		TextOut(hdc, WINDOW_WIDTH - 40, 2, _T("X"), strlen("X"));
	}
	else if (!isClose)
	{
		SetTextColor(hdc, RGB(255, 255, 255));
		TextOut(hdc, WINDOW_WIDTH - 40, 2, _T("X"), strlen("X"));
		SetTextColor(hdc, RGB(50, 50, 200));
		TextOut(hdc, WINDOW_WIDTH - 40, 2, _T("O"), strlen("O"));
	}
	if (win){
		win = false;
		SelectObject(hdc, hFont2);
		SetBkMode(hdc, TRANSPARENT);    //设置输出文字背景色为透明
		SetTextColor(hdc, RGB(255, 0, 0));
		TextOut(hdc, WINDOW_WIDTH / 2 - 200, WINDOW_HEIGHT / 2 - 150, _T("YOU WIN!"), strlen("YOU WIN!"));
	}
	if (final){
		SelectObject(hdc, hBrush1);
		Rectangle(hdc, 0, WINDOW_HEIGHT/2-150, WINDOW_WIDTH, WINDOW_HEIGHT/2+150);
		SelectObject(hdc, hFont2);
		SetBkMode(hdc, TRANSPARENT);    //设置输出文字背景色为透明
		SetTextColor(hdc, RGB(255, 0, 0));
		TextOut(hdc, WINDOW_WIDTH / 2 - 380, WINDOW_HEIGHT / 2 - 90, _T("恭喜你完成所有关卡!"), strlen("恭喜你完成所有关卡!"));
	}
	DeleteObject(hFont1);//释放字体对象
	DeleteObject(hFont2); 
	DeleteObject(hBrush);
	DeleteObject(hBrush1); 
	DeleteObject(hBrush2);
	DeleteObject(hBrush3);
	DeleteObject(hBrush4);
}
//鼠标位置响应
void MouseMove(HWND hwnd, int x, int y, WPARAM wParam)
{
	POINT pt = { x, y }; //定义鼠标单击点
	RECT rect = { WINDOW_WIDTH - 40, 0, WINDOW_WIDTH - 8, 24 };//×的位置
	RECT rect2 = { WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2+10, WINDOW_WIDTH / 2 + 90, WINDOW_HEIGHT / 2 + 90 };//Start的位置
	RECT rectrest = { 520 + 10, WINDOW_HEIGHT - 200, 520 + 10 + 100, WINDOW_HEIGHT - 200 + 18 };
	hdc = GetDC(hwnd);
	if (PtInRect(&rect, pt) && isClose)//鼠标移到×和○
	{
		isClose = false;
		TextFace(hdc);
	}
	if (!PtInRect(&rect, pt) && !isClose)
	{
		isClose = true;
		TextFace(hdc);
	}
	if (PtInRect(&rect2, pt) && isStart)//鼠标移到Start
	{
		isStart = false;
		DrawFace(hdc);
	}
	if (!PtInRect(&rect2, pt) && !isStart)
	{
		isStart = true;
		DrawFace(hdc);
	}
}
//鼠标点击
void MouseClick(HWND hwnd, int x, int y, WPARAM wParam)
{
	POINT pt = { x, y };		//定义鼠标单击点
	RECT rectc = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
	RECT rectclose = { WINDOW_WIDTH - 40, 0, WINDOW_WIDTH - 8, 24 };
	RECT rectstart = { WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2-10, WINDOW_WIDTH / 2 + 70, WINDOW_HEIGHT / 2 + 70 };//Start的位置
	if (PtInRect(&rectc, pt))//在指定方形区域,可移动窗口!
		PostMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, wParam);
	if (PtInRect(&rectclose, pt))
		DestroyWindow(hwnd);		// 销毁窗口, 并发送一条WM_DESTROY消息;
	if (PtInRect(&rectstart, pt))
		isBegin = false;
}
//删除画板
bool CleanUp(HWND hwnd)
{
	ReleaseDC(hwnd, hdc);
	DeleteDC(hdc);
	return TRUE;
}
//绘制地图
void DrawMap(HDC hdc){
	int k = 0;
	//画迷宫
	RECT rect;
	HRGN hrgn;//画圆
	HBRUSH hBrush, hBrush1, hBrush2, hBrush3, hBrush4;
	hBrush = CreateSolidBrush(RGB(150, 150, 150));
	hBrush1 = CreateSolidBrush(RGB(180, 220, 230));
	hBrush2 = CreateSolidBrush(RGB(100, 0, 100));
	hBrush3 = CreateSolidBrush(RGB(50, 100, 120));
	hBrush4 = CreateSolidBrush(RGB(255, 150, 150));
	HFONT hFont1 = CreateFont(100, 0, 0, 0, FW_HEAVY, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, _T("微软雅黑"));
	for (int i = 0; i < 11; i++) {
		for (int j = 0; j < 11; j++) {
			switch (GameMap[i][j]){
			case 1://地图边界
				rect.bottom = (i + 1) * 50;
				rect.left = j * 50;
				rect.right = (j + 1) * 50;
				rect.top = i * 50;
				FillRect(hdc, &rect, hBrush1);//用指定画刷填充
				break;
			case 2:
				//人
				hrgn = CreateEllipticRgn(j * 50, i * 50, (j + 1) * 50, (i + 1) * 50);
				FillRgn(hdc, hrgn, hBrush2);
				break;
			case 7:
				//人在成功点
				rect.bottom = (i + 1) * 50;
				rect.left = j * 50;
				rect.right = (j + 1) * 50;
				rect.top = i * 50;
				FillRect(hdc, &rect, hBrush);
				hrgn = CreateEllipticRgn(j * 50, i * 50, (j + 1) * 50, (i + 1) * 50);
				FillRgn(hdc, hrgn, hBrush2);
				break;
			case 3:
				//箱子
				rect.bottom = (i + 1) * 50;
				rect.left = j * 50;
				rect.right = (j + 1) * 50;
				rect.top = i * 50;
				FillRect(hdc, &rect, hBrush3);
				break;
			case 5:
				//成功点
				rect.bottom = (i + 1) * 50;
				rect.left = j * 50;
				rect.right = (j + 1) * 50;
				rect.top = i * 50;
				FillRect(hdc, &rect, hBrush);
				break;
			case 8:
				//箱子推到成功点
				rect.bottom = (i + 1) * 50;
				rect.left = j * 50;
				rect.right = (j + 1) * 50;
				rect.top = i * 50;
				FillRect(hdc, &rect, hBrush4);
				break;
			default:
				break;
			}
			if (3 == GameMap[i][j])
				k++;
		}
	}
	//胜利
	if (k == 0){
		win = true;
		
		nextMap(hdc);
		steps = 0;
	}
	DeleteObject(hFont1);//释放字体对象
	DeleteObject(hBrush);
	DeleteObject(hBrush1);
	DeleteObject(hBrush2);
	DeleteObject(hBrush3);
	DeleteObject(hBrush4);
}
//移动
void PlayGame(WPARAM wParam){
	int i, j;
	for ( i = 1; i<11; i++)//获得人的坐标
	{
		for ( j = 1; j<11; j++)
		{
			if (GameMap[i][j] == 2 || GameMap[i][j] == 7)
			{
				PosX = i;
				PosY = j;
				break;//跳出第一个for循环
			}
		}
		if (GameMap[i][j] == 2 || GameMap[i][j] == 7)//跳出第二个for循环
			break;

	}
	switch (wParam)
	{
	case 'A':
	case 'a':
	case VK_LEFT:
		PosX1 = PosX; PosY1 = PosY;
		memcpy(RecantMap, GameMap, sizeof(RecantMap));//保存上一步
		if (GameMap[PosX][PosY - 1] == 0 || GameMap[PosX][PosY - 1] == 5){//判断下一个位置是否为空地或成功点
			//地图的数据改变
			GameMap[PosX][PosY - 1] += 2;//人进来
			GameMap[PosX][PosY] -= 2;//人离开
			InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
			PosY -= 1;//玩家的坐标改变
			steps++;//步数增加
		}
		else if (3 == GameMap[PosX][PosY - 1] || 8 == GameMap[PosX][PosY - 1])//下一个位置是箱子
		{
			if (1 == GameMap[PosX][PosY - 2] || 3 == GameMap[PosX][PosY - 2] || 8 == GameMap[PosX][PosY - 2]);
			else
			{
				//地图的数据改变
				GameMap[PosX][PosY - 2] += 3;//箱子移动
				GameMap[PosX][PosY - 1] -= 1;//人进来
				GameMap[PosX][PosY] -= 2;//人离开
				InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
				PosY -= 1;//玩家的坐标改变
				steps++;//步数增加
			}
		}
		break;
	case 'D':
	case 'd':
	case VK_RIGHT:
		PosX1 = PosX; PosY1 = PosY;
		memcpy(RecantMap, GameMap, sizeof(RecantMap));//保存上一步
		if (0 == GameMap[PosX][PosY + 1] || 5 == GameMap[PosX][PosY + 1])//判断下一个位置是否为空地或成功点
		{
			//地图的数据改变
			GameMap[PosX][PosY + 1] += 2;//人进来
			GameMap[PosX][PosY] -= 2;//人离开
			InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
			PosY += 1;//玩家的坐标改变
			steps++;//步数增加
		}
		else if (3 == GameMap[PosX][PosY + 1] || 8 == GameMap[PosX][PosY + 1])//下一个位置是箱子
		{
			if (1 == GameMap[PosX][PosY + 2] || 3 == GameMap[PosX][PosY + 2] || 8 == GameMap[PosX][PosY + 2]);
			else
			{
				//地图的数据改变
				GameMap[PosX][PosY + 2] += 3;//箱子移动
				GameMap[PosX][PosY + 1] -= 1;//人进来
				GameMap[PosX][PosY] -= 2;//人离开
				InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
				PosY += 1;//玩家的坐标改变
				steps++;//步数增加
			}
		}
		break;
	case 'W':
	case 'w':
	case VK_UP:
		PosX1 = PosX; PosY1 = PosY;
		memcpy(RecantMap, GameMap, sizeof(RecantMap));//保存上一步
		if (0 == GameMap[PosX - 1][PosY] || 5 == GameMap[PosX - 1][PosY])//判断下一个位置是否为空地或成功点
		{
			//地图的数据改变
			GameMap[PosX - 1][PosY] += 2;//人进来
			GameMap[PosX][PosY] -= 2;//人离开
			InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
			PosX -= 1;//玩家的坐标改变
			steps++;//步数增加
		}
		else if (3 == GameMap[PosX - 1][PosY] || 8 == GameMap[PosX - 1][PosY])//下一个位置是箱子
		{
			if (1 == GameMap[PosX - 2][PosY] || 3 == GameMap[PosX - 2][PosY] || 8 == GameMap[PosX - 2][PosY]);
			else
			{
				//地图的数据改变
				GameMap[PosX - 2][PosY] += 3;//箱子移动
				GameMap[PosX - 1][PosY] -= 1;//人进来
				GameMap[PosX][PosY] -= 2;//人离开
				InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
				PosX -= 1;//玩家的坐标改变
				steps++;//步数增加
			}
		}
		break;
	case 'S':
	case 's':
	case VK_DOWN:
		PosX1 = PosX; PosY1 = PosY;
		memcpy(RecantMap, GameMap, sizeof(RecantMap));//保存上一步
		if (0 == GameMap[PosX + 1][PosY] || 5 == GameMap[PosX + 1][PosY])//判断下一个位置是否为空地或成功点
		{
			//地图的数据改变
			GameMap[PosX + 1][PosY] += 2;//人进来
			GameMap[PosX][PosY] -= 2;//人离开
			InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
			PosX += 1;//玩家的坐标改变
			steps++;//步数增加
		}
		else if (3 == GameMap[PosX + 1][PosY] || 8 == GameMap[PosX + 1][PosY])//下一个位置是箱子
		{
			if (1 == GameMap[PosX + 2][PosY] || 3 == GameMap[PosX + 2][PosY] || 8 == GameMap[PosX + 2][PosY]);
			else
			{
				//地图的数据改变
				GameMap[PosX + 2][PosY] += 3;//箱子移动
				GameMap[PosX + 1][PosY] -= 1;//人进来
				GameMap[PosX][PosY] -= 2;//人离开
				InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
				PosX += 1;//玩家的坐标改变
				steps++;//步数增加
			}
		}
		break;
	case 'p':
	case 'P'://重玩
		memcpy(GameMap, TempMap, sizeof(GameMap));
		//PosX = 1; PosY = 2;
		steps = 0;
		InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
		break;
	case 'c':
	case 'C'://撤销
		memcpy(GameMap, RecantMap, sizeof(GameMap));
		PosX = PosX1; PosY = PosY1;
		steps -= 1;
		InvalidateRect(hWnd, NULL, TRUE);//重新绘制窗口
		break;
	}
}
//进入下一关
void nextMap(HDC hdc){
	if (nextm)
	{
		for (int i = 0; i < 11; i++) {
			for (int j = 0; j < 11; j++) {
				if (GameMap[i][j] == 8)
				{
					box++;
				}
			}
		}
		nextm = false;
	}
	
		if (box == 3)
		{
			if (mapNumGoing < 3)
			{
				mapNumGoing++;
			}
			else if (mapNumGoing = 3)
			{
				final = true;
			}
			mapNumGoingC = mapNumGoing;
			mapNumWait = true;
			nextm = true;
			box = 0;
			textc = true;
			MapChange();
		}
	}
//切换地图
void MapChange(){
	if (mapNumWait){
		for (int i = 0; i < 11; i++) {
			for (int j = 0; j < 11; j++) {
				switch (mapNumGoing)
				{
				case 1:
					GameMap[i][j] = Map[0][i][j];
					memcpy(TempMap, GameMap, sizeof(GameMap));//把初始地图复制到临时地图
					break;
				case 2:
					GameMap[i][j] = Map[1][i][j];
					memcpy(TempMap, GameMap, sizeof(GameMap));//把初始地图复制到临时地图
					break;
				case 3:
					GameMap[i][j] = Map[2][i][j];
					memcpy(TempMap, GameMap, sizeof(GameMap));//把初始地图复制到临时地图
					break;
				}
			}
		}
		mapNumWait = false;
	}
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

代码很长,希望看完了的同学可以获得自己想要的知识,也感谢大家的耐心观看,在这里想得到大家一波关注,后续UP主还会发布更多的项目源码以及学习资料,有什么问题可以回帖留言,我尽量回答。想要C/C++学习资料以及其他项目的源码的可以加群【768440837】了解。想要对程序员的未来发展有兴趣的也可加群闲聊。希望和大家一起学习进步!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值