推箱子——学完C语言简单实现小游戏

  •                    *推箱子是一款非常经典的游戏,我们一起来实现它吧!*
    

一:要完成这个游戏,首先要知道实现那些功能,需要哪些知识点。
1.实现图形的界面*
二维数组,初始化赋值,图形库贴图
2.人物的移动
for循环,switch,以及人物推动箱子等等一切逻辑的判断!
人物往前走的时候,遇到的情况:
①.人物面前是空地,人往前走,对人原本位置进行判断,如果站在目的地就是3,如果站在空地就是0,进行赋值
②.人面前是站在空地上的箱子,再判断箱子的面前是空地还是空的目的地,箱子往前走,人往前走,站在原本箱子呆的地方,人站在空地上,人原本的位置也要进行判断,再赋值
③:人面前是空的目的地,人进入空目的地,对人原本的位置进行判断,人可以站在空地也可以站在空的目的地上
④:人面前是进入目的地的箱子,判断箱子的面前是什么,空地还是空目的地,箱子往前走,人进入箱子原本的位置,箱子离开了,人也就是进入空目的地,再判断人原本的位置,进行赋值
3.游戏的胜利条件
判断胜利的函数,判断失败的条件
4.第一关胜利之后,会自动换关

5.播放音乐
6.悔棋功能:
*用另一个数组,保存我们人物移动的时候,还没动的时候的位置,如果要悔棋,就替换呢元素
二:运行结果给大家看看


三:接下面来编写代码

/************************************************************************
*                项目名称:推箱子
*                项目描述:按键操作
*                项目环境:VS2013
*                生成日期:2019-11-20
*                作者所属:追梦
*************************************************************************/
#include<stdio.h>
#include<easyx.h>
#include<stdlib.h>
#include<conio.h>//_getch()函数的头文件
#include<Windows.h>
#include"resource.h"
#pragma comment(lib,"winmm.lib")//添加库,音乐
int arr[3][10][10] =
{
	{
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 0, 0, 0, 0, 4, 0, 0, 0, 1 },
		{ 1, 0, 0, 0, 0, 2, 4, 3, 0, 1 },
		{ 1, 0, 0, 0, 0, 0, 4, 0, 0, 1 },
		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
		{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
		{ 1, 3, 1, 0, 0, 0, 0, 0, 3, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	},
	{
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 3, 0, 1, 0, 0, 0, 0, 3, 1 },
		{ 1, 0, 0, 1, 0, 0, 4, 0, 0, 1 },
		{ 1, 0, 0, 1, 0, 4, 0, 0, 0, 1 },
		{ 1, 0, 0, 1, 0, 2, 0, 1, 1, 1 },
		{ 1, 4, 0, 1, 0, 0, 4, 0, 0, 1 },
		{ 1, 0, 0, 0, 0, 3, 0, 0, 0, 1 },
		{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
		{ 1, 3, 1, 0, 0, 1, 0, 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, 3, 1, 0, 0, 0, 3, 0, 1 },
		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 1 },
		{ 1, 1, 0, 0, 0, 4, 0, 0, 0, 1 },
		{ 1, 1, 0, 0, 4, 2, 4, 0, 0, 1 },
		{ 1, 1, 1, 1, 0, 0, 4, 0, 0, 1 },
		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
		{ 1, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
		{ 1, 3, 4, 0, 0, 3, 0, 0, 3, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	},
};//这个关卡难易程度自己改

int map[10][10];//游玩时候的地图
int map1[10][10];//保存移动前的数组的值
IMAGE image[6];//图片数组
int life = 0;//判断游戏胜利
int level = 0;//第几关

void drawMenu()
{
	initgraph(640, 450);
	setbkcolor(WHITE);
	cleardevice();
	setfillcolor(BLUE);
	settextstyle(30, 0, "宋体");
	setbkmode(TRANSPARENT);
	fillrectangle(240, 100, 380, 150);
	fillrectangle(240, 100 + 60, 380, 150 + 60);
	outtextxy(240 + 13, 100 + 13, "开始游戏");
	outtextxy(240 + 13, 100 + 13 + 60, "退出游戏");
	settextcolor(RED);
	outtextxy(130, 280, "追梦团队拼图游戏v1.2.0版本");
	MOUSEMSG m;
	while (1)
	{
		m = GetMouseMsg();
		if (m.x >= 240 && m.x <= 380 && m.y >= 100 && m.y <= 150)
		{
			setlinecolor(BLACK);
			rectangle(240 - 5, 100 - 5, 380 + 5, 150 + 5);
			if (m.uMsg == WM_LBUTTONDOWN)
			{
				break;
			}
		}
		else if (m.x >= 240 && m.x <= 380 && m.y >= 160 && m.y <= 210)
		{
			setlinecolor(BLACK);
			rectangle(240 - 5, 160 - 5, 380 + 5, 210 + 5);
			if (m.uMsg == WM_LBUTTONDOWN)
			{
				exit(0);
			}
		}
		else
		{
			setlinecolor(WHITE);
			rectangle(240 - 5, 100 - 5, 380 + 5, 150 + 5);
			rectangle(240 - 5, 160 - 5, 380 + 5, 210 + 5);
		}
	}
	closegraph();
}
//初始化地图
void init()
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			map[i][j] = arr[level][i][j];
		}
	}
}

//贴图
void drawmap()
{
	BeginBatchDraw();//开始批量贴图
	putimage(0, 0, &image[0]);//贴背景
	for (int i = 0; i < 10; i++)//for循环遍历map地图的所有元素进行贴图
	{
		for (int j = 0; j < 10; j++)
		{
			switch (map[i][j])//判断地图元素进行对应的贴图
			{
			case 1://墙的贴图
				putimage(50 * j, 50 * i, &image[1]);
				putimage(0, 0, &image[1]);
				break;
			case 2://人的贴图
				putimage(50 * j, 50 * i, &image[2]);
				break;
			case 3://目的地的贴图
				putimage(50 * j, 50 * i, &image[3]);
				break;
			case 4://箱子的贴图
				putimage(50 * j, 50 * i, &image[4]);
				break;
			case 5://箱子进入目的地的贴图
				putimage(50 * j, 50 * i, &image[5]);
				break;
			case 6://人进入目的地的贴图
				putimage(50 * j, 50 * i, &image[2]);
				break;
			}
		}
	}
	EndBatchDraw();//结束批量贴图
}

//悔棋函数
void huiqi()//记录还没移动的时候,数组元素的值
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			map1[i][j] = map[i][j];
		}
	}
}

//移动
void play()
{
	int i, j;//表示人在数组中的下标
	for (int n = 0; n < 10; n++)//遍历数组找人的位置
	{
		for (int m = 0; m < 10; m++)
		{
			if (map[n][m] == 2 || map[n][m] == 6)//找到了人
			{
				i = n;
				j = m;
			}
		}
	}
	char key = _getch();//_getch()是字符按键接收,不会回显到控制台
	switch (key)//判断按键
	{
	case'r':case'R'://回撤一步
		for (int i = 0; i < 10; i++)
		{
			for (int j = 0; j < 10; j++)
			{
				map[i][j] = map1[i][j];
			}
		}
		break;
	case'w':case'W'://区分大小写
		huiqi();//保存还没移动前的数据
		if (map[i - 1][j] == 0)//如果人面前是空地
		{
			map[i - 1][j] = 2;//人往前走
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i - 1][j] == 3)//人面前是空的目的地
		{
			map[i - 1][j] = 6;//人站在目的地里面
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i - 1][j] == 4)//人得面前是空地上的箱子
		{
			if (map[i - 2][j] == 0)//箱子的面前是空地
			{
				map[i - 2][j] = 4;//箱子推到空地上
				map[i - 1][j] = 2;//人站在箱子原本的位置上
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i - 2][j] == 3)//箱子的前面是空的目的地
			{
				map[i - 2][j] = 5;//箱子推进目的地里
				map[i - 1][j] = 2;//人进入原本箱子的位置
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		else if (map[i - 1][j] == 5)//人的面前是站在目的地的箱子
		{
			if (map[i - 2][j] == 0)//箱子的面前是空地
			{
				map[i - 2][j] = 4;//箱子推到空地上
				map[i - 1][j] = 6;//人站在目的地上了
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i - 2][j] == 3)//箱子的面前是空的目的地
			{
				map[i - 2][j] = 5;//箱子推到目的地
				map[i - 1][j] = 6;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		break;
	case's':case'S':
		huiqi();//保存还没移动前的数据
		if (map[i + 1][j] == 0)//如果人面前是空地
		{
			map[i + 1][j] = 2;//人往前走
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i + 1][j] == 3)//人面前是空的目的地
		{
			map[i + 1][j] = 6;//人站在目的地里面
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i + 1][j] == 4)//人得面前是空地上的箱子
		{
			if (map[i + 2][j] == 0)//箱子的面前是空地
			{
				map[i + 2][j] = 4;//箱子推到空地上
				map[i + 1][j] = 2;//人站在箱子原本的位置上
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i + 2][j] == 3)//箱子的前面是空的目的地
			{
				map[i + 2][j] = 5;//箱子推进目的地里
				map[i + 1][j] = 2;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		else if (map[i + 1][j] == 5)//人的面前是站在目的地的箱子
		{
			if (map[i + 2][j] == 0)//箱子的面前是空地
			{
				map[i + 2][j] = 4;//箱子推到空地上
				map[i + 1][j] = 6;//人站在目的地上了
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i + 2][j] == 3)//箱子的面前是空的目的地
			{
				map[i + 2][j] = 5;//箱子推到目的地
				map[i + 1][j] = 6;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		break;
	case'a':case'A':
		huiqi();//保存还没移动前的数据
		if (map[i][j - 1] == 0)//如果人面前是空地
		{
			map[i][j - 1] = 2;//人往前走
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i][j - 1] == 3)//人面前是空的目的地
		{
			map[i][j - 1] = 6;//人站在目的地里面
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i][j - 1] == 4)//人得面前是空地上的箱子
		{
			if (map[i][j - 2] == 0)//箱子的面前是空地
			{
				map[i][j - 2] = 4;//箱子推到空地上
				map[i][j - 1] = 2;//人站在箱子原本的位置上
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i][j - 2] == 3)//箱子的前面是空的目的地
			{
				map[i][j - 2] = 5;//箱子推进目的地里
				map[i][j - 1] = 2;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		else if (map[i][j - 1] == 5)//人的面前是站在目的地的箱子
		{
			if (map[i][j - 2] == 0)//箱子的面前是空地
			{
				map[i][j - 2] = 4;//箱子推到空地上
				map[i][j - 1] = 6;//人站在目的地上了
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i][j - 2] == 3)//箱子的面前是空的目的地
			{
				map[i][j - 2] = 5;//箱子推到目的地
				map[i][j - 1] = 6;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		break;
	case'd':case'D':
		huiqi();//保存还没移动前的数据
		if (map[i][j + 1] == 0)//如果人面前是空地
		{
			map[i][j + 1] = 2;//人往前走
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i][j + 1] == 3)//人面前是空的目的地
		{
			map[i][j + 1] = 6;//人站在目的地里面
			//对人本身进行判断
			if (map[i][j] == 6)//如果人本身是站在目的地里
				map[i][j] = 3;//恢复成空目的地
			else//人站在空地
				map[i][j] = 0;//恢复成空地
		}
		else if (map[i][j + 1] == 4)//人得面前是空地上的箱子
		{
			if (map[i][j + 2] == 0)//箱子的面前是空地
			{
				map[i][j + 2] = 4;//箱子推到空地上
				map[i][j + 1] = 2;//人站在箱子原本的位置上
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i][j + 2] == 3)//箱子的前面是空的目的地
			{
				map[i][j + 2] = 5;//箱子推进目的地里
				map[i][j + 1] = 2;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		else if (map[i][j + 1] == 5)//人的面前是站在目的地的箱子
		{
			if (map[i][j + 2] == 0)//箱子的面前是空地
			{
				map[i][j + 2] = 4;//箱子推到空地上
				map[i][j + 1] = 6;//人站在目的地上了
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
			else if (map[i][j + 2] == 3)//箱子的面前是空的目的地
			{
				map[i][j + 2] = 5;//箱子推到目的地
				map[i][j + 1] = 6;
				//对人本身进行判断
				if (map[i][j] == 6)//如果人本身是站在目的地里
					map[i][j] = 3;//恢复成空目的地
				else//人站在空地
					map[i][j] = 0;//恢复成空地
			}
		}
		break;
	}
}

//判断游戏胜利
void win()
{
	int number = 0;//假设所有的箱子都进入了目的地,地图上就没有了箱子,number用来表示站在空地上的箱子的数量
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			if (map[i][j] == 4)//说明空地上还有箱子
				number++;
		}
	}
	for (int i = 0; i < 10; i++)//判断游戏失败
	{
		for (int j = 0; j < 10; j++)
		{
			if (map[i][j] == 4)//对某个箱子进行判断
			{
				if (map[i - 1][j] == 1 || map[i + 1][j] == 1)//判断上下是否有一个是围墙
				{
					if (map[i][j - 1] == 1 || map[i][j + 1] == 1)
						//判断左右是否有一个是围墙
					{
						life = 2;//游戏失败
					}
				}
			}
		}
	}

	if (number == 0)//如果地图上站在空地上的箱子数为0
		life = 1;//表示游戏胜利
}
int main()
{
	drawMenu();
	initgraph(500, 500);//初始化图形环境
	//loadimage(&image[0], "背景.PNG", 500, 500);//加载背景图片
	//loadimage(&image[1], "墙.PNG", 50, 50);//墙
	//loadimage(&image[2], "推人.PNG", 50, 50);//人
	//loadimage(&image[3], "目的地.PNG", 50, 50);//目的地
	//loadimage(&image[4], "箱子.png", 50, 50);//箱子
	//loadimage(&image[5], "箱子和目的地重合.PNG", 50, 50);//箱子和目的地重合

	//把图片资源导入到项目,可直接点exe文件运行
	loadimage(&image[0], "PNG", MAKEINTRESOURCE(IDB_PNG1), 500, 500);
	loadimage(&image[1], "PNG", MAKEINTRESOURCE(IDB_PNG3), 50, 50);
	loadimage(&image[2], "PNG", MAKEINTRESOURCE(IDB_PNG4), 50, 50);
	loadimage(&image[3], "PNG", MAKEINTRESOURCE(IDB_PNG2), 50, 50);
	loadimage(&image[4], "PNG", MAKEINTRESOURCE(IDB_PNG5), 50, 50);
	loadimage(&image[5], "PNG", MAKEINTRESOURCE(IDB_PNG6), 50, 50);

	init();//初始化地图
	drawmap();//给地图元素贴图
	mciSendString("open attheage.mp3", 0, 0, 0);//打开
	mciSendString("play attheage.mp3", 0, 0, 0);//播放
	//Sleep(5000);//延迟五秒
	//mciSendString("stop attheage.mp3", 0, 0, 0);//停止

	while (1)
	{
		play();//移动一次
		drawmap();//贴一次图
		win();//判断游戏是否胜利
		if (life == 1)//游戏胜利
		{
			if (MessageBox(GetHWnd(), "游戏胜利!", "是否要继续游戏?", MB_YESNO) == IDYES)//弹窗,按下'是',进入if语句
			{
				life = 0;//下次循环不会进入if语句
				level++;//关卡+1
				if (level == 3)//说明第三关结束了
				{
					if (MessageBox(GetHWnd(), "最后一关!", "是否要回到第一关!", MB_YESNO) == IDYES)//按下'是',进入if语句,回到第一关
					{
						level = 0;
					}
					else return 0;
				}
				init();//重新初始化
				drawmap();//贴图
			}
			else return 0;//按下'否',退出程序
		}
		if (life == 2)//游戏失败
		{
			life = 0;
			if (MessageBox(GetHWnd(), "游戏失败!", "是否重新开始本关卡", MB_YESNO) == IDYES)//按下'是',重新开始游戏
			{
				init();
				drawmap();
			}
		}
	}
	system("pause");
	closegraph();//关闭图形库
	return 0;
}

主要还是人物的移动,弄清楚一个方向之后,其他的方向只需要稍微修改一下即可。

发布了3 篇原创文章 · 获赞 5 · 访问量 196

猜你喜欢

转载自blog.csdn.net/qq_45893999/article/details/104701652