欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于easyx图形库的推箱子小游戏

程序员文章站 2024-03-18 10:04:10
...

基于easyx图形库的推箱子小游戏

C语言期末项目要求自己设计一个项目,我选择了《推箱子》小游戏,
因为这个程序当中涉及到的一些算法及语法,能够更好的帮助我复习有关C语言的基础知识。
这是我的第一篇博客,希望大家多多指正。

程序效果图

基于easyx图形库的推箱子小游戏

基于easyx图形库的推箱子小游戏图片是我自己在网上扣的,所以不怎么美观

项目实现(主要算法)

利用数字矩阵表示地图,不同的数字代表不同的图片。
程序遍历数组,遇到不同的数字贴相应的图片

程序代码

主程序:

```c

```c

```c

```c
```c
#include"Thehead.h"//引用头文件

int map_temp_last[100][16][16];//用于保存上一步的地图
int map_temp[MapMany][16][16];//用于保存上一关的地图

int stepnum = 0;//统计步数
char input;//用户的键入操作
//设置窗口大小
int main()
{
	ReadMapFile();
	//PlaySound(TEXT("gamemusic.wav"), 0, SND_FILENAME | SND_ASYNC);

	F:
	Welcome();

	//保存本关的地图,在执行之前保存,便于执行重启操作

	for (int i = 0; i < 16; i++)
		for (int j = 0; j < 16; j++)
			map_temp[WhatMap][i][j] = map[WhatMap][i][j];

	while (1)
	{
		//判断是否进入下一关
		MOUSEMSG msg2;
		{
			while (MouseHit())	//监听鼠标信息;当有鼠标消息的时候执行,可检测连续的鼠标信息
			{
				msg2 = GetMouseMsg();//获取鼠标消息
				if (WM_LBUTTONDOWN == msg2.uMsg)//判断鼠标信息;鼠标左键按下
				{
					if (msg2.x > 860 && msg2.x < 940 && msg2.y > 50 && msg2.y < 110)
					{
						

```c
if(WhatMap<10)
							WhatMap++;
						
					}
					else if (msg2.x > 790 && msg2.x < 850 && msg2.y > 50 && msg2.y < 110)//鼠标点击特定区域`在这里插入代码片`
					{
						if (WhatMap >= 1)
							WhatMap--;
				}

				else if (msg2.x > 10 && msg2.x < 50 && msg2.y > 50 && msg2.y < 90)//鼠标点击特定区域
				{
					goto F;
				}
				drawGame();
			}

		}
	}
	

	if (kbhit())
	{


		PlaySound(TEXT("move.wav"), 0, SND_FILENAME | SND_ASYNC);
		input = getch();
		{

			if (input == 'W' || input == 'w' || input == 72)
			{
				ManUp();

			}
			else if (input == 'S' || input == 's' || input == 80)
			{
				ManDown();

			}
			else if (input == 'A' || input == 'a' || input == 75)
			{
				ManLeft();

			}
			else if (input == 'D' || input == 'd' || input == 77)
			{
				ManRight();

			}
			else if (input == 'r' || input == 'R')
			{
				Reset();

			}
			else if (input == 'z' || input == 'Z')
			{
				if (stepnum > 0) {
					stepnum--;
					Backstep();
				}
			}
			
			else
				continue;

		}

		drawGame();//每次移动后都要从新贴图,因此没执行一步调用一次该函数

		if (GameOver())
		{
			PlaySound(TEXT("success.wav"), 0, SND_FILENAME | SND_ASYNC);
			WhatMap++;//如果一个关卡完成,则进入下一个关卡
			stepnum = 0;
			for (int i = 0; i < 16; i++)
				for (int j = 0; j < 16; j++)
					map_temp[WhatMap][i][j] = map[WhatMap][i][j];
			Sleep(1000);
		}
		if (WhatMap == 11)break;
	}
}

Sleep(10000);
return 0;
//system("pause");

}

//初始化窗口,加载图片
void initscreen()
{
initgraph(16 * (SPACE+20), 16 * SPACE);//初始化画图窗口

outtextxy(700, 50, "目标数:");
// 加载图片

//0表示空地//1表示墙//2代表目的地//3代表人站在空地上//4代表箱子
//5箱子与目的地重合// 6,人站在目的地上
loadimage(&png[0], _T("0.jpg"), SPACE, SPACE, true);
loadimage(&png[1], _T("1.jpg"), SPACE, SPACE, true);
loadimage(&png[2], _T("2.jpg"), SPACE, SPACE, true);
loadimage(&png[3], _T("3.jpg"), SPACE, SPACE, true);
loadimage(&png[4], _T("4.jpg"), SPACE, SPACE, true);
loadimage(&png[5], _T("5.jpg"), SPACE, SPACE, true);
loadimage(&png[6], _T("6.jpg"), SPACE, SPACE, true);
loadimage(&button, _T("button.jpg"), 150, 60, true);
loadimage(&next, _T("next.jpg"), 60, 60, true);
loadimage(&previous, _T("previous.jpg"), 60, 60, true);
loadimage(&backto, _T("backto.jpg"), 60, 60, true);
drawGame();

}
//画出游戏中的各个元素(贴图的方式)
void drawGame() {
for (int i = 0; i < 16; i++) {//显示一行
for (int j = 0; j < 16; j++) {//显示一个格子
putimage(j * SPACE, i * SPACE, &png[map[WhatMap][i][j]]);
}
}

putimage(100, 50, &button);
putimage(350, 50, &button);
putimage(600, 50, &button);
putimage(860, 50, &next);
putimage(790, 50, &previous);
putimage(10, 50, &backto);
setbkmode(TRANSPARENT);//设置字体背景为透明
settextcolor(COLORREF(RGB(255, 0, 0)));//设置字体颜色为黑色
settextstyle(40, 0, _T("楷体"));//设置字体大小20,格式楷体

//将数字通过字符的形式输出
TCHAR t1[5];
TCHAR t2[5];
TCHAR t3[5];
_stprintf(t1, _T("%d"), WhatMap + 1);	// 高版本 VC 推荐使用 _stprintf_s 函数
_stprintf(t2, _T("%d"), stepnum);
_stprintf(t3, _T("%d"), Boxnum());
outtextxy(200, 50, t1);
outtextxy(100, 50, "关卡:");

outtextxy(450, 50, t2);
outtextxy(350, 50, "步数:");

outtextxy(730, 50, t3);
outtextxy(600, 50, "目标数:");

outtextxy(1000, 50, "撤回:z键");
outtextxy(1000, 100, "重启本关:r键");
outtextxy(1000, 150, "操作:a、w、s、");
outtextxy(1000, 200, "d或者方向键");
outtextxy(1000, 400, "其余操作用鼠标");

}

void ManDown()
{

//在每一步执行之前,将地图保存到临时数组里面
int p, q;
for (int i = 0; i < 16; i++)
	for (int j = 0; j < 16; j++)
		map_temp_last[stepnum][i][j] = map[WhatMap][i][j];

//先找到人的位置
int i, j;
for (i = 0; i < 16; i++)
{
	int flag = 0;
	for (j = 0; j < 16; j++)
		if (map[WhatMap][i][j] == 3 || map[WhatMap][i][j] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}
//人的位置是map[WhatMap][i][j];


//人的位置是空地(而不是人和目的地在一起)
if (map[WhatMap][i][j] == 3)
{
	//人的上面是空地
	if (map[WhatMap][i + 1][j] == 0)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i + 1][j] = 3;
	}
	//人的上面是目的地
	else if (map[WhatMap][i + 1][j] == 2)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i + 1][j] = 6;
	}
	//人的上面是箱子
	else if (map[WhatMap][i + 1][j] == 4)
	{
		//1箱子上面是目的地
		if (map[WhatMap][i + 2][j] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i + 1][j] = 3;
			map[WhatMap][i + 2][j] = 5;
		}
		//2箱子上面是空地
		else if (map[WhatMap][i + 2][j] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i + 1][j] = 3;
			map[WhatMap][i + 2][j] = 4;
		}

	}
	//人的上面是箱子和目的地在一起
	else if (map[WhatMap][i + 1][j] == 5)
	{
		//箱子上面是目的地
		if (map[WhatMap][i + 2][j] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i + 1][j] = 6;
			map[WhatMap][i + 2][j] = 5;
		}

		//箱子上面是空地
		else if (map[WhatMap][i + 2][j] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i + 1][j] = 6;
			map[WhatMap][i + 2][j] = 4;
		}
	}

}

//人的位置是目的地(即人和目的地在一起)
else if (map[WhatMap][i][j] == 6)
{

	//人的上面是空地

	if (map[WhatMap][i + 1][j] == 0)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i + 1][j] = 3;
	}
	//人的上面是目的地
	else if (map[WhatMap][i + 1][j] == 2)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i + 1][j] = 6;
	}
	//人的上面是箱子

	else if (map[WhatMap][i + 1][j] == 4)
	{
		//1.箱子上面是目的地
		if (map[WhatMap][i + 2][j] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i + 1][j] = 3;
			map[WhatMap][i + 2][j] = 5;
		}
		//2.箱子上面是空地
		else if (map[WhatMap][i + 2][j] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i + 1][j] = 3;
			map[WhatMap][i + 2][j] = 4;
		}

	}


	//人的上面是箱子和目的地在一起
	else if (map[WhatMap][i + 1][j] == 5)
	{
		//箱子上面是目的地
		if (map[WhatMap][i + 2][j] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i + 1][j] = 6;
			map[WhatMap][i + 2][j] = 5;
		}

		//箱子上面是空地
		else if (map[WhatMap][i + 2][j] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i + 1][j] = 6;
			map[WhatMap][i + 2][j] = 4;
		}
	}
}

//防止回到上一步也在增加步数
for (p = 0; p < 16; p++)
{
	int flag = 0;
	for (q = 0; q < 16; q++)
		if (map[WhatMap][p][q] == 3 || map[WhatMap][p][q] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}

//将现在人的步数和刚开始人的步数进行比较,如果相同,则不进行步数的增加
if (i != p || j != q)
	stepnum++;

}
//人向右移动
void ManRight()
{
int p, q;

for (int i = 0; i < 16; i++)
	for (int j = 0; j < 16; j++)
		map_temp_last[stepnum][i][j] = map[WhatMap][i][j];
//先找到人的位置
int i, j;
for (i = 0; i < 16; i++)
{
	int flag = 0;
	for (j = 0; j < 16; j++)
		if (map[WhatMap][i][j] == 3 || map[WhatMap][i][j] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}
//人的位置是map[WhatMap][i][j];



//人的位置是空地
if (map[WhatMap][i][j] == 3)
{
	//人的右面是空地
	if (map[WhatMap][i][j + 1] == 0)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i][j + 1] = 3;
	}
	//人的右面是目的地
	else if (map[WhatMap][i][j + 1] == 2)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i][j + 1] = 6;
	}
	//人的右面是箱子
	else if (map[WhatMap][i][j + 1] == 4)
	{
		//1.箱子右面是目的地
		if (map[WhatMap][i][j + 2] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j + 1] = 3;
			map[WhatMap][i][j + 2] = 5;
		}
		//2.箱子右面是空地
		else if (map[WhatMap][i][j + 2] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j + 1] = 3;
			map[WhatMap][i][j + 2] = 4;
		}

	}


	//人的右边是箱子和目的地在一起
	else if (map[WhatMap][i][j + 1] == 5)
	{
		//箱子右边是目的地
		if (map[WhatMap][i][j + 2] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j + 1] = 6;
			map[WhatMap][i][j + 2] = 5;
		}

		//箱子右边是空地
		else if (map[WhatMap][i][j + 2] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j + 1] = 6;
			map[WhatMap][i][j + 2] = 4;
		}
	}
}

//人的位置是目的地
else if (map[WhatMap][i][j] == 6)
{
	//人的右面是空地

	if (map[WhatMap][i][j + 1] == 0)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j + 1] = 3;
	}
	//人的右面是目的地
	else if (map[WhatMap][i][j + 1] == 2)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j + 1] = 6;
	}
	//人的右面是箱子

	else if (map[WhatMap][i][j + 1] == 4)
	{
		//1.箱子右面是目的地
		if (map[WhatMap][i][j + 2] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j + 1] = 3;
			map[WhatMap][i][j + 2] = 5;
		}
		//2.箱子右面是空地
		else if (map[WhatMap][i][j + 2] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j + 1] = 3;
			map[WhatMap][i][j + 2] = 4;
		}

	}


	//人的右边是箱子和目的地在一起
	else if (map[WhatMap][i][j + 1] == 5)
	{
		//箱子右边是目的地
		if (map[WhatMap][i][j + 2] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j + 1] = 6;
			map[WhatMap][i][j + 2] = 5;
		}

		//箱子右边是空地
		else if (map[WhatMap][i][j + 2] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j + 1] = 6;
			map[WhatMap][i][j + 2] = 4;
		}
	}
}
for (p = 0; p < 16; p++)
{
	int flag = 0;
	for (q = 0; q < 16; q++)
		if (map[WhatMap][p][q] == 3 || map[WhatMap][p][q] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}

if (i != p || j != q)
	stepnum++;

}

//人向左移动
void ManLeft()
{
int p, q;

for (int i = 0; i < 16; i++)
	for (int j = 0; j < 16; j++)
		map_temp_last[stepnum][i][j] = map[WhatMap][i][j];
//先找到人的位置
int i, j;
for (i = 0; i < 16; i++)
{
	int flag = 0;
	for (j = 0; j < 16; j++)
		if (map[WhatMap][i][j] == 3 || map[WhatMap][i][j] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}
//人的位置是map[WhatMap][i][j];

//改变人的方向

//人的位置是空地
if (map[WhatMap][i][j] == 3)
{
	//人的左面是空地
	if (map[WhatMap][i][j - 1] == 0)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i][j - 1] = 3;
	}
	//人的左面是目的地
	else if (map[WhatMap][i][j - 1] == 2)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i][j - 1] = 6;
	}
	//人的左面是箱子
	else if (map[WhatMap][i][j - 1] == 4)
	{
		//1.箱子左面是目的地
		if (map[WhatMap][i][j - 2] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j - 1] = 3;
			map[WhatMap][i][j - 2] = 5;
		}
		//2.箱子左面是空地
		else if (map[WhatMap][i][j - 2] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j - 1] = 3;
			map[WhatMap][i][j - 2] = 4;
		}

	}

	//人的左边是箱子和目的地在一起
	else if (map[WhatMap][i][j - 1] == 5)
	{
		//箱子右边是目的地
		if (map[WhatMap][i][j - 2] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j - 1] = 6;
			map[WhatMap][i][j - 2] = 5;
		}

		//箱子右边是空地
		else if (map[WhatMap][i][j - 2] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i][j - 1] = 6;
			map[WhatMap][i][j - 2] = 4;
		}
	}
}


//人的位置是目的地
else if (map[WhatMap][i][j] == 6)
{
	//人的上面是空地

	if (map[WhatMap][i][j - 1] == 0)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j - 1] = 3;
	}
	//人的上面是目的地
	else if (map[WhatMap][i][j - 1] == 2)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j - 1] = 6;
	}
	//人的上面是箱子

	else if (map[WhatMap][i][j - 1] == 4)
	{
		//1.箱子上面是目的地
		if (map[WhatMap][i][j - 2] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j - 1] = 3;
			map[WhatMap][i][j - 2] = 5;
		}
		//2.箱子上面是空地
		else if (map[WhatMap][i][j - 2] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i][j - 1] = 3;
			map[WhatMap][i][j - 2] = 4;
		}

	}
}
//人的左边是箱子和目的地在一起
else if (map[WhatMap][i][j - 1] == 5)
{
	//箱子左边是目的地
	if (map[WhatMap][i][j - 2] == 2)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j - 1] = 6;
		map[WhatMap][i][j - 2] = 5;
	}

	//箱子左边是空地
	else if (map[WhatMap][i][j + 2] == 0)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i][j - 1] = 6;
		map[WhatMap][i][j - 2] = 4;
	}
}
for (p = 0; p < 16; p++)
{
	int flag = 0;
	for (q = 0; q < 16; q++)
		if (map[WhatMap][p][q] == 3 || map[WhatMap][p][q] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}

if (i != p || j != q)
	stepnum++;

}

//人向下移动
void ManUp()
{
int p, q;
for (int i = 0; i < 16; i++)
for (int j = 0; j < 16; j++)
map_temp_last[stepnum][i][j] = map[WhatMap][i][j];
//先找到人的位置
int i, j;
for (i = 0; i < 16; i++)
{
int flag = 0;
for (j = 0; j < 16; j++)
if (map[WhatMap][i][j] == 3 || map[WhatMap][i][j] == 6)//人站在空地上或者人站在目的地上
{
flag = 1;
break;
}
if (flag)break;
}

//人的位置已被记录
//人的位置是map[WhatMap][i][j];

//1.人的位置是空地
if (map[WhatMap][i][j] == 3)
{
	//人的上面是空地
	if (map[WhatMap][i - 1][j] == 0)
	{
		map[WhatMap][i][j] = 0;//人变空地
		map[WhatMap][i - 1][j] = 3;//空地变人
	}
	//人的上面是目的地
	else if (map[WhatMap][i - 1][j] == 2)
	{
		map[WhatMap][i][j] = 0;
		map[WhatMap][i - 1][j] = 6;//人和目的地咱一起
	}
	//人的上面是箱子
	else if (map[WhatMap][i - 1][j] == 4)
	{
		//1.箱子上面是目的地
		if (map[WhatMap][i - 2][j] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i - 1][j] = 3;
			map[WhatMap][i - 2][j] = 5;
		}
		//2.箱子上面是空地
		else if (map[WhatMap][i - 2][j] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i - 1][j] = 3;
			map[WhatMap][i - 2][j] = 4;
		}

	}
	//人的上面是箱子和目的地在一起
	else if (map[WhatMap][i - 1][j] == 5)
	{
		//箱子上面是目的地
		if (map[WhatMap][i - 2][j] == 2)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i - 1][j] = 6;
			map[WhatMap][i - 2][j] = 5;
		}

		//箱子上面是空地
		else if (map[WhatMap][i - 2][j] == 0)
		{
			map[WhatMap][i][j] = 0;
			map[WhatMap][i - 1][j] = 6;
			map[WhatMap][i - 2][j] = 4;
		}
	}
}

//人的位置是目的地
else if (map[WhatMap][i][j] == 6)
{
	//人的上面是空地

	if (map[WhatMap][i - 1][j] == 0)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i - 1][j] = 3;
	}
	//人的上面是目的地
	else if (map[WhatMap][i - 1][j] == 2)
	{
		map[WhatMap][i][j] = 2;
		map[WhatMap][i - 1][j] = 6;
	}

	//人的上面是箱子(有两种情况)

	else if (map[WhatMap][i - 1][j] == 4)
	{
		//1箱子上面是目的地
		if (map[WhatMap][i - 2][j] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i - 1][j] = 3;
			map[WhatMap][i - 2][j] = 5;
		}
		//2箱子上面是空地
		else if (map[WhatMap][i - 2][j] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i - 1][j] = 3;
			map[WhatMap][i - 2][j] = 4;
		}

	}
	//人的上面是箱子和目的地在一起
	else if (map[WhatMap][i - 1][j] == 5)
	{
		//箱子上面是目的地
		if (map[WhatMap][i - 2][j] == 2)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i - 1][j] = 6;
			map[WhatMap][i - 2][j] = 5;
		}

		//箱子上面是空地
		else if (map[WhatMap][i - 2][j] == 0)
		{
			map[WhatMap][i][j] = 2;
			map[WhatMap][i - 1][j] = 6;
			map[WhatMap][i - 2][j] = 4;
		}
	}
}
for (p = 0; p < 16; p++)
{
	int flag = 0;
	for (q = 0; q < 16; q++)
		if (map[WhatMap][p][q] == 3 || map[WhatMap][p][q] == 6)
		{
			flag = 1;
			break;
		}
	if (flag)break;
}

if (i != p || j != q)
	stepnum++;

}

//判断游戏是否结束
int GameOver()
{
//统计目的地的个数
//每个地图的目的地个数不同,因此每次都要遍历地图数组
int flag = 0;
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
if (map[WhatMap][i][j] == 2)flag++;
}
}

//箱子到达目的地的个数
//当箱子和目的地在一起的个数和目的地总数相等,则该关卡已完成
int count = 0;
for (int i = 0; i < 16; i++)
{
	for (int j = 0; j < 16; j++)
	{
		if (map[WhatMap][i][j] == 4)count++;
	}
}
if (count == 0 && flag == 0)return 1;
else return 0;

}

//显示初始页面
void Welcome()
{
initgraph(16 * SPACE, 16 * SPACE);//初始化画图窗口

loadimage(&welcome, "welcome.jpg", 16 * SPACE, 16 * SPACE);//导入欢迎界面(特别注意:双引号里面不能有空格,要跟图片命名完全一致)
loadimage(&Create, "Create.jpg", 300, 100);
loadimage(&Create, "Create.jpg", 300, 100);
loadimage(&Create, "Create.jpg", 300, 100);
loadimage(&Create, "Create.jpg", 300, 100);

putimage(0, 0, &welcome);//显示欢迎界面
putimage(300, 100, &Create);
putimage(300, 200, &Create);
putimage(300, 300, &Create);
putimage(300, 400, &Create);

setbkmode(TRANSPARENT);//设置字体背景为透明
settextcolor(COLORREF(RGB(128, 255, 0)));//设置字体颜色为黑色

settextstyle(50, 0, _T("宋体"));//设置字体大小20,格式楷体
char r1[] = "地图编辑";
char r2[] = "开始游戏";
char r3[] = "退出游戏";
char r4[] = "游戏说明";
outtextxy(350, 430, r1);
outtextxy(350, 130, r2);
outtextxy(350, 230, r3);
outtextxy(350, 330, r4);

MOUSEMSG msg;//定义变量,保存鼠标消息
FlushMouseMsgBuffer();// 清空鼠标消息缓冲区,避免无效鼠标信息带入到正式判断中
while (true) // 主循环,循环监听鼠标信息
{
	while (MouseHit())	//监听鼠标信息;当有鼠标消息的时候执行,可检测连续的鼠标信息
	{
		msg = GetMouseMsg();//获取鼠标消息
		if (WM_LBUTTONDOWN == msg.uMsg)//判断鼠标信息;鼠标左键按下
		{
			if (msg.x > 300 && msg.x < 900 && msg.y > 100 && msg.y < 200)//鼠标点击特定区域
			{
				initscreen(); return;
			}
			else if (msg.x > 300 && msg.x < 900 && msg.y > 200 && msg.y < 300)
			{
				exit(0);
			}
			else if (msg.x > 300 && msg.x < 900 && msg.y > 300 && msg.y < 400)
			{
				ShowText();
				getch();
				Welcome();
				return;

			}
			else if (msg.x > 300 && msg.x < 900 && msg.y > 400 && msg.y < 500)
				CreatMap();
			return;
		}

	}

}

}

//显示帮助文档
void ShowText()
{
initgraph(16 * SPACE, 16 * SPACE);
loadimage(&helptext, “helptext.jpg”, 16 * SPACE, 16 * SPACE);
putimage(0, 0, &helptext);

setbkmode(TRANSPARENT);//设置字体背景为透明
settextcolor(COLORREF(RGB(0, 0, 0)));//设置字体颜色为黑色
settextstyle(40, 0, _T("楷体"));//设置字体大小20,格式楷体
char s1[] = "这是一个经典的推箱子游戏";
char s2[] = "使用方向键↑←↓→或者“w、a、s、d";
char s3[] = "(不区分大小写)控制人物来推动箱子";
char s4[] = "游戏开发者:扎扎西(单身可撩)";
char s5[] = "开发时间:2020.5.18";
char s6[] = "所有箱子到达目的地即可通关";
char s7[] = "按R/r键重启关卡,按Z/z键撤回前一步操作";
char s8[] = "除游戏控制外的操作支持鼠标点击";
char s9[] = "按任意键返回!!";
outtextxy(150, 270, s6);
outtextxy(150, 150, s1);
outtextxy(150, 190, s2);
outtextxy(150, 230, s3);
outtextxy(400, 450, s4);
outtextxy(400, 490, s5);
outtextxy(150, 310, s7);
outtextxy(150, 350, s8);
outtextxy(150, 610, s9);

}

//重置当前关卡
void Reset()
{
stepnum = 0;//因为重启,步数归零
for (int i = 0; i < 16; i++) //显示一行
for (int j = 0; j < 16; j++) //显示一个格子
map[WhatMap][i][j] = map_temp[WhatMap][i][j];
}

//实现撤回功能
void Backstep()
{

if (stepnum < 0)
	return;
for (int i = 0; i < 16; i++) //显示一行
	for (int j = 0; j < 16; j++) //显示一个格子
		map[WhatMap][i][j] = map_temp_last[stepnum][i][j];

}

/

/

```c
统计当前关卡中剩余的目的地数
int Boxnum()
{
	int boxnum = 0;
	for (int m = 0; m < 16; m++)
		for (int n = 0; n < 16; n++)
		if (map[WhatMap][m][n] == 4)
			boxnum++;
return boxnum;

}







## 创建地图部分

```c
//#include"Thehead.h"//引用头文件
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#define SPACE 60
#include<graphics.h>
#include<stdbool.h>
#include<string.h>;
void ShowhelpTxt();
IMAGE png1[12];//5张图,定义5个变量,定义一个数组
IMAGE background;
IMAGE conti;
#define N 16    //地图宽高

#define FLMOP "NewMap.txt"

void gotoxy(int x, int y);  //光标定位
void TranMap();              //翻译输出地图
void Control();            //控制移动和设置元素函数

int cmap[N][N];      //地图数组
char ck;            //读方向键
int x, y;           //光标坐标(x*2)

int CreatMap()                 //主函数控制所有
{
	initgraph(16 * SPACE, 16 * SPACE);//初始化画图窗口

	//输出使用说明
	ShowhelpTxt();
	TranMap();              //输出地图

	while (1)
	{


		Control(); //控制光标移动


	}

	Sleep(60);
	return 0;


}

void dszcz()             //编辑结束后输出数组
{

	char s[] = "是否确认保存地图,确认请按Y";
	outtextxy(250, 50, s);
	char tch = _getch();

	if (tch != 'y') return;     //输入y确认继续

	FILE* fp = NULL;            //将地图数组保存进所选文件路径中
	fopen_s(&fp, FLMOP, "a+");  //追加方式打开文件

	if (fp)
	{
		for (int i = 0; i < N; i++) //将地图信息写入文件
		{
			for (int j = 0; j < N; j++)
				fprintf(fp, "%d ", cmap[i][j]);
			fprintf(fp, "\n");

		}
		fprintf(fp, "\n");
		fclose(fp);
	}

	char q[] = "恭喜!地图信息添加成功";
	outtextxy(250, 50, q);

	exit(0);
}

void Control()
{
	loadimage(&png1[0], _T("0.jpg"), SPACE, SPACE, true);
	loadimage(&png1[1], _T("1.jpg"), SPACE, SPACE, true);
	loadimage(&png1[2], _T("2.jpg"), SPACE, SPACE, true);
	loadimage(&png1[3], _T("3.jpg"), SPACE, SPACE, true);
	loadimage(&png1[4], _T("4.jpg"), SPACE, SPACE, true);
	loadimage(&png1[5], _T("5.jpg"), SPACE, SPACE, true);


	ck = _getch();              //接收

	switch (ck)
	{
	case 'w':
	
		y--;          //光标移动
		if (y < 0)          //对光标的移动位置加以限制
		{
			y = 0;
			return;
		}
		break;

	case 'a':
	
		x--;
		if (x < 0)
		{
			x = 0;
			return;
		}
		break;

	case 's':
	
		y++;
		if (y > 15)
		{
			y = 15;
			return;
		}
		break;

	case 'd':
	
		x++;
		if (x > 15)
		{
			x = 15;
			return;
		}
		break;

	case '1':
		putimage(x * SPACE, y * SPACE, &png1[1]); break;
	case '2':
		putimage(x * SPACE, y * SPACE, &png1[2]); break;
	case '3':
		putimage(x * SPACE, y * SPACE, &png1[3]); break;
	case '4':
		putimage(x * SPACE, y * SPACE, &png1[4]); break;
	default:   putimage(x * SPACE, y * SPACE, &png1[0]);
		ck = '0';    //输入其他ch为0空格,就是打印空地
		break;
	case 'z':
		dszcz();            //z结束编辑地图
	}

	if (ck != 'w' && ck != 'a' && ck != 's' && ck != 'd' && ck != 'z')  //不是移动和保存时,将ck值存储进数组中
		cmap[y][x] = ck - '0';
}

void TranMap()       //输出初始地图
{
	loadimage(&png1[0], _T("0.jpg"), SPACE, SPACE, true);
	loadimage(&png1[1], _T("1.jpg"), SPACE, SPACE, true);
	loadimage(&png1[2], _T("2.jpg"), SPACE, SPACE, true);
	loadimage(&png1[3], _T("3.jpg"), SPACE, SPACE, true);
	loadimage(&png1[4], _T("4.jpg"), SPACE, SPACE, true);
	loadimage(&png1[5], _T("5.jpg"), SPACE, SPACE, true);
	loadimage(&png1[6], _T("6.jpg"), SPACE, SPACE, true);
	int i, j;           //循环用变量
	//gotoxy(0, 0);
	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
		{
			putimage(j * SPACE, i * SPACE, &png1[cmap[i][j]]);
		}

	}

}


void ShowhelpTxt()
{
	loadimage(&background, "background.jpg", 16 * SPACE, 16 * SPACE);
	putimage(0, 0, &background);//显示界面
	loadimage(&conti, "continue.jpg", 100, 50);
	putimage(600, 600, &conti);
	//显示文档文字
	setbkmode(TRANSPARENT);//设置字体背景为透明
	settextcolor(COLORREF(RGB(0, 0, 0)));//设置字体颜色为黑色
	settextstyle(40, 0, _T("楷体"));//设置字体大小20,格式楷体
	char c1[] = "显示16*16的地图方格";
	char c2[] = "使用“w、a、s、d";
	char c3[] = "移动光标(记得调成英文输入法)";
	char c4[] = "左上角第一格为光标的坐标(0,0),以此类推";
	char c5[] = "按下1将光标处设置为墙,2设置为目标";
	char c6[] = "3设置为人,4设置为箱子,其余部分自动认为空地";
	char c7[] = "按z保存地图。如果想要使用自己的地图";
	char c8[] = "则需要更改路径为Newmap.txt!";
	outtextxy(150, 270, c4);
	outtextxy(150, 150, c1);
	outtextxy(150, 190, c2);
	outtextxy(150, 230, c3);
	outtextxy(150, 390, c7);
	outtextxy(150, 430, c8);
	outtextxy(150, 310, c5);
	outtextxy(150, 350, c6);

	MOUSEMSG msg1;
	while (true) // 主循环,循环监听鼠标信息
	{
		while (MouseHit())	//监听鼠标信息;当有鼠标消息的时候执行,可检测连续的鼠标信息
		{
			msg1 = GetMouseMsg();//获取鼠标消息
			if (WM_LBUTTONDOWN == msg1.uMsg)//判断鼠标信息;鼠标左键按下
			{
				if (msg1.x > 600 && msg1.x < 700 && msg1.y > 600 && msg1.y < 650)//鼠标点击特定区域
				{
					return;
				}

			}

		}

	}
	return;
}