c语言实现推箱子小游戏

c语言实现推箱子小游戏

项目主要步骤

  1. 使用二维数组创建一个地图并初始化地图
  2. 接收用户的键盘的按键,实现人物的移动
  3. 判断哪些情况人物和箱子可以走,哪些情况不能走
  4. 判断是否过关

函数模块分析

使用二维数组创建一个地图

int map1[13][14] = {															//创建一个地图
	{ 0,0,0,0,2,2,2,2,2,2,0,0,0,0 },					// 0: 空地		
	{ 0,0,0,0,2,0,0,0,0,2,0,0,0,0 },					// 1: 目的地  ☆
	{ 0,2,2,2,2,0,0,0,0,2,2,2,2,2 },					// 2: 墙壁    ■
	{ 0,2,0,0,0,2,0,0,0,0,0,0,0,2 },					// 4: 箱子	  □
	{ 0,2,0,4,0,0,0,4,0,0,0,4,0,2 },					// 8: 玩家    ♀
	{ 0,2,0,0,0,2,2,0,2,2,2,2,2,2 },					// 16:箱子已在目的地  ★
	{ 2,2,2,2,0,0,0,0,0,0,0,0,0,2 },					// 32:人在目的地上  ♂
	{ 2,0,0,0,0,0,2,0,0,0,8,0,0,2 },
	{ 2,0,4,0,0,0,2,0,2,2,2,2,2,2 },
	{ 2,2,0,0,0,0,2,0,2,0,1,1,2,0 },
	{ 0,2,0,2,0,0,0,0,0,0,1,1,2,0 },
	{ 0,2,0,0,0,0,2,2,0,0,0,0,2,0 },
	{ 0,2,2,2,2,2,2,2,2,2,2,2,2,0 }
};

各个数字所代表的图标已在注释中说明,在次不再说明

接着初始化该地图

void init_map1()									//初始化该地图
{
	int row;
	int col;
	for (row = 0; row < sizeof(map1) / sizeof(map1[0]); row++)
	{
		printf("     ");
		for (col = 0; col < sizeof(map1[0]) / sizeof(map1[0][0]); col++)
		{
			switch (map1[row][col])
			{
			case 0:
				printf("%s", "  ");
				break;
			case 1:
				printf("%s", "☆");
				break;
			case 2:
				printf("%s", "■");
				break;
			case 4:
				printf("%s", "□");
				break;
			case 8:
				printf("%s", "♀");
				break;
			case 16:
				printf("%s", "★");
				break;
			case 32:
				printf("%s", "♂");
				break;
			default:
				break;
			}
		}
		printf("\n");
	}
}

所打印出来的地图如下:
在这里插入图片描述

​ 颜色性由两个十六进制数字指定, 第一个为背景色, 第二个为前景色。
​ 每个数字可以为下列值之一:
​ 黑色 = 0 蓝色 = 1 绿色 = 2 湖蓝色 = 3
​ 红色 = 4 紫色 = 5 黄色 = 6 白色 = 7
​ 灰色 = 8 淡蓝色=9 淡绿色=A 白色=C
​ 淡紫色=D 淡黄色=E 亮白色=F
这里我设置背景色为紫色,文字颜色为淡黄色
system(“color 5e”);

判断是否通关

int is_win_map1(void)
{
	int row;
	int col;
	int num = 0;
	for (row = 0; row < sizeof(map1) / sizeof(map1[0]); row++)
	{
		for (col = 0; col < sizeof(map1[0]) / sizeof(map1[0][0]); col++)
		{
			if (map1[row][col] == 4)
				num++;
		}
	}
	if (num == 0)
	{
		printf("游戏结束,恭喜你过关!\n");
		return 0;
	}
	return 1;
}

如果在地图中没有箱子了,就说明通关了,游戏结束

游戏的逻辑核心:判断什么情况下人物和箱子可以移动

void player_game_map1(int row, int col)
{
	int perrow, percol;
	int i;
	int j;
	for (i = 0; i < sizeof(map1) / sizeof(map1[0]); i++)
	{
		for (j = 0; j < sizeof(map1[0]) / sizeof(map1[0][0]); j++)
		{
			if (map1[i][j] == 8 || map1[i][j] == 32)
			{
				perrow = i;
				percol = j;
			}
		}
	}

/* 首先遍历整个数组,找到人物的位置,将值赋给`perrow`和`percol`两个变量,代表人物的位置坐标 */
    
	if (map1[perrow + row][percol + col] == 0)
	{
		if (map1[perrow][percol] == 32)
		{
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 1;
		}
		else
		{
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		return;
	}

/* 如果人物的前面是空地,则进入该if语句。如果人物在目的地上,向前移动的话,则让人物前面的符号为
8(人物),让原先人物所在的位置为1(目的地)。否则,人物只能在空地上,人物向前移动的话,让人物前面
的符号为8(人物),人物原先所在的位置的符号为0(空地) */

	if (map1[perrow + row][percol + col] == 1)
	{
		if (map1[perrow][percol] == 32)
		{
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 1;
		}
		else
		{
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 0;
		}
		return;
	}

/* 如果人物前面是目的地,则进入该if语句。如果人物已在目的地上,向前移动,则让人物下一个位置为
32(人加目的地),原先位置为1(目的地)。否则,说明人物在原先在空地上,前面是目的地,向前移动的话,
让移动后的位置为32(人加目的地),原先的位置为0(空地) */

	if (map1[perrow + row][percol + col] == 4)
	{
		if (map1[perrow + row + row][percol + col + col] == 0)
		{
			map1[perrow + row + row][percol + col + col] = 4;
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		if (map1[perrow + row + row][percol + col + col] == 1)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		return;
	}

/* 如果人物前面是箱子的话,进入该if语句。人物前面是箱子,如果箱子的前面是空地的话,则把箱子前面
的那个位置赋值为4(箱子),原先箱子的位置赋值为8(人物),原先人物的地方赋值为0(空地) 。人物前面是
箱子,如果箱子的前面是目的地的话,则把目的地赋值为16(箱子加目的地),原先箱子的位置赋值为8(人物),
原先人物的地方赋值为0(空地) */

	if (map1[perrow + row][percol + col] == 16)
	{
		if (map1[perrow][percol] == 32
			&& map1[perrow + row + row][percol + col + col] == 1)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 32;		
             map1[perrow][percol] = 1;
		}
		if (map1[perrow][percol] == 32
			&& map1[perrow + row + row][percol + col + col] == 0)
		{
			map1[perrow + row + row][percol + col + col] = 4;
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 1;
			return;
		}
		if (map1[perrow + row + row][percol + col + col] == 1)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 0;
		}
		return;
	}

/* 如果人物前面是16(人物加目的地),则进入该if语句。如果人物已在目的地上并且人物前面的前面是1(目的
地),则把这个位置赋值为16(箱子加目的地),把人物前面的位置赋值为32(人加目的地),把人物原先的位置赋值
为1(目的地)。如果人物在目的地上并且人物前面的前面是空地,则把人物前面的前面这个位置赋值为4(箱子),
把人物前面的位置赋值为32(人加目的地),把人物原先的位置赋值为1(目的地)。最后一种情况,人物原先在空
地上,人物前面是16(箱子加目的地),人物前面的前面是目的地,则把人物前面的前面所在的位置赋值为16
(箱子加目的地),把人物前面的位置赋值为32(人加目的地),人物原先的位置赋值为0(空地) */
}

最后,主函数

int main()
{
	int a;
	system("mode con cols=40 lines=15");
	system("color 5e");
	init_map1();
	do
	{
		switch (getch())
		{
		case 'w':
			player_game_map1(-1, 0);
			break;
		case 's':
			player_game_map1(1, 0);
			break;
		case 'a':
			player_game_map1(0, -1);
			break;
		case 'd':
			player_game_map1(0, 1);
			break;
		default:
			printf("输入错误\n");
			break;
		}
		system("cls");
		init_map1();
	} while (is_win_map1());
	system("pause");
	return 0;
}

项目整体源码

到此,我们c语言实现的推箱子小游戏就大功告成了,这个地图是比较简单的,你也可以自己在后面加上一些比较难的关卡,下面附上源码,供大家参考和指正

#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<Windows.h>
int map1[13][14] = {															//创建一个地图
	{ 0,0,0,0,2,2,2,2,2,2,0,0,0,0 },					// 0: 空地		
	{ 0,0,0,0,2,0,0,0,0,2,0,0,0,0 },					// 1: 目的地  ☆
	{ 0,2,2,2,2,0,0,0,0,2,2,2,2,2 },					// 2: 墙壁    ■
	{ 0,2,0,0,0,2,0,0,0,0,0,0,0,2 },					// 4: 箱子	  □
	{ 0,2,0,4,0,0,0,4,0,0,0,4,0,2 },					// 8: 玩家    ♀
	{ 0,2,0,0,0,2,2,0,2,2,2,2,2,2 },					// 16:箱子已在目的地  ★
	{ 2,2,2,2,0,0,0,0,0,0,0,0,0,2 },					// 32:人在目的地上  ♂
	{ 2,0,0,0,0,0,2,0,0,0,8,0,0,2 },
	{ 2,0,4,0,0,0,2,0,2,2,2,2,2,2 },
	{ 2,2,0,0,0,0,2,0,2,0,1,1,2,0 },
	{ 0,2,0,2,0,0,0,0,0,0,1,1,2,0 },
	{ 0,2,0,0,0,0,2,2,0,0,0,0,2,0 },
	{ 0,2,2,2,2,2,2,2,2,2,2,2,2,0 }
};

void init_map1()									//初始化该地图
{
	int row;
	int col;
	for (row = 0; row < sizeof(map1) / sizeof(map1[0]); row++)
	{
		printf("     ");
		for (col = 0; col < sizeof(map1[0]) / sizeof(map1[0][0]); col++)
		{
			switch (map1[row][col])
			{
			case 0:
				printf("%s", "  ");
				break;
			case 1:
				printf("%s", "☆");
				break;
			case 2:
				printf("%s", "■");
				break;
			case 4:
				printf("%s", "□");
				break;
			case 8:
				printf("%s", "♀");
				break;
			case 16:
				printf("%s", "★");
				break;
			case 32:
				printf("%s", "♂");
				break;
			default:
				break;
			}
		}
		printf("\n");
	}
}
int is_win_map1(void)
{
	int row;
	int col;
	int num = 0;
	for (row = 0; row < sizeof(map1) / sizeof(map1[0]); row++)
	{
		for (col = 0; col < sizeof(map1[0]) / sizeof(map1[0][0]); col++)
		{
			if (map1[row][col] == 4)
				num++;
		}
	}
	if (num == 0)
	{
		printf("游戏结束,恭喜你过关!\n");
		return 0;
	}
	return 1;
}
void player_game_map1(int row, int col)
{
	int perrow, percol;
	int i;
	int j;
	for (i = 0; i < sizeof(map1) / sizeof(map1[0]); i++)
	{
		for (j = 0; j < sizeof(map1[0]) / sizeof(map1[0][0]); j++)
		{
			if (map1[i][j] == 8 || map1[i][j] == 32)
			{
				perrow = i;
				percol = j;
			}
		}
	}
	if (map1[perrow + row][percol + col] == 0)
	{
		if (map1[perrow][percol] == 32)
		{
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 1;
		}
		else
		{
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		return;
	}
	if (map1[perrow + row][percol + col] == 1)
	{
		if (map1[perrow][percol] == 32)
		{
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 1;
		}
		else
		{
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 0;
		}
		return;
	}
	if (map1[perrow + row][percol + col] == 4)
	{
		if (map1[perrow + row + row][percol + col + col] == 0)
		{
			map1[perrow + row + row][percol + col + col] = 4;
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		if (map1[perrow + row + row][percol + col + col] == 1)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 8;
			map1[perrow][percol] = 0;
		}
		return;
	}
	if (map1[perrow + row][percol + col] == 16)
	{
		if (map1[perrow][percol] == 32
			&& map1[perrow + row + row][percol + col + col] == 1)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 1;
		}
		if (map1[perrow][percol] == 32
			&& map1[perrow + row + row][percol + col + col] == 0)
		{
			map1[perrow + row + row][percol + col + col] = 4;
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 1;
			return;
		}
		if (map1[perrow + row + row][percol + col + col] != 16 && map1[perrow + row + row][percol + col + col] != 2)
		{
			map1[perrow + row + row][percol + col + col] = 16;
			map1[perrow + row][percol + col] = 32;
			map1[perrow][percol] = 0;
		}
		return;
	}
}
int main()
{
	int a;
	system("mode con cols=40 lines=15");
	system("color 5e");
	init_map1();
	do
	{
		switch (getch())
		{
		case 'w':
			player_game_map1(-1, 0);
			break;
		case 's':
			player_game_map1(1, 0);
			break;
		case 'a':
			player_game_map1(0, -1);
			break;
		case 'd':
			player_game_map1(0, 1);
			break;
		default:
			printf("输入错误\n");
			break;
		}
		system("cls");
		init_map1();
	} while (is_win_map1());
	system("pause");
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值