基于easyx图形库的推箱子小游戏
C语言期末项目要求自己设计一个项目,我选择了《推箱子》小游戏,
因为这个程序当中涉及到的一些算法及语法,能够更好的帮助我复习有关C语言的基础知识。
这是我的第一篇博客,希望大家多多指正。
程序效果图
图片是我自己在网上扣的,所以不怎么美观
项目实现(主要算法)
利用数字矩阵表示地图,不同的数字代表不同的图片。
程序遍历数组,遇到不同的数字贴相应的图片
程序代码
主程序:
```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;
}