推箱子

用c/c++写一个推箱子小游戏(特别详细)

主要用到数组。非常简单,入门必写的小游戏。下面代码呈现,地图做得非常简单,可以的话自己修改,有什么错误,请大佬指正。

我觉得有意思的是移动那一块,因为该开始写的时候,每移动一步,就要做出处理,这就导致了做了很多重复的代码,这没有意义。因为没使用函数,所以没想到,这些大量重复的代码,相似的代码,完全可以将他封装起来。

数组,写这个游戏,我第一次用到三维数组,Map[0][][] 表示关卡,Map[][10][10]表示地图,以前真没写过这些。说到数组,这有些坑,我是这样觉得的,对于初学者而言,因为写多了int 型的,一说到数组就会想到数组。这对学结构体很不好,数组只是开辟了一段连续的空间,只是这段空间存什么值不确定需要强制指出来。
#include<iostream>
#include<conio.h>
#include<stdlib.h>
#include<Windows.h>
#include<time.h>
using namespace std;

//推箱子的地图:
//0表示空地、1表示墙、2表示玩家、3表示箱子、4表示成功点 6.表示人与成功点重合,7代表箱子和成功点重合
//6表示玩家和成功点重合、7表示箱子和成功点重合。
//功能实现 :
//1.判断胜利;
//2.切换关卡(至少3关)
//3.重玩
//4.撤销(选做)
//
//查询资料:
//1.彩色文字
//2.无阻塞输入



int main()
{
	int Map[3][10][10] = {
		{{1,1,1,1,1,1,1,1,1,1},//关卡1
		{1,1,1,1,1,1,1,1,1,1},
		{1,1,0,0,0,1,1,1,1,1},
		{1,1,0,3,0,1,1,1,1,1},
		{1,1,1,1,0,1,0,0,1,1},
		{1,1,1,0,0,0,0,0,1,1},
		{1,1,2,0,0,1,0,0,1,1},
		{1,1,0,0,0,1,0,0,4,1},
		{1,1,1,1,1,1,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1},},

		{
		{1,1,1,1,1,1,1,1,1,1},//关卡2
		{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,4,1,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,3,0,0,1,0,3,0,1},
		{1,0,0,1,0,0,0,0,0,1},
		{1,1,2,1,4,0,0,0,1,1},
		{1,1,1,1,1,1,0,0,0,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,0,0,0,4,0,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,0,3,0,0,0,0,0,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,0,0,0,0,0,0,0,1},
		{1,0,2,0,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1},},
	};/* 地图 */

	int MapBuffer[10][10];/* 地图备份以便重玩 */
	memcpy(MapBuffer, Map[0], sizeof(Map[0]));//将Map中的数据拷贝到MapBuffer中
	int PosX, PosY;//玩家位置,x 代表行, y代表列
	int OffSetX = 0, OffSetY = 0;//表示按键后的偏移量
	bool bFlag = false;//标志记录是否撤销了一步
	int numberSuccess = 0, Success = 0;
	int level = 0;//游戏关卡
	int Input;//键
	for (level; level < 3; level++)
	{
		memcpy(MapBuffer, Map[level], sizeof(Map[level]));//将Map中的数据拷贝到MapBuffer中
		numberSuccess = 0, Success = 0;//从新记录
		for (int i = 0; i < 10; i++)
		{
			for (int j = 0; j < 10; j++)
			{
				if(2 == Map[level][i][j])
					PosX = i, PosY = j;
				if (4 == Map[level][i][j])
					numberSuccess++;
			}
		}
		while (true)
		{
			/* 打印地图 */
			for (int i = 0; i < 10; i++)
			{
				for (int j = 0; j < 10; j++)
				{
					switch (Map[level][i][j])
					{
					case 0:
						cout << "  ";/* 路 这里要隔2个空格*/
						break;
					case 1:
						cout << "■";/* 墙 */
						break;
					case 2:
					case 6:
						cout << "♀";/* 人 */
						break;
					case 3:
					case 7:
						cout << "●";/* 箱子 */
						break;
					case 4:
						cout << "○";/* 成功点 */
						break;
					}//switch
				}//for j
				cout << endl;
			}//for i
			Input = _getch();//控制玩家行为
			system("CLS");//清屏
			switch (Input)
			{
			case 'w':
			case 'W':/* 向上走 */
				OffSetX = -1, OffSetY = 0;
				break;
			case 's':
			case 'S':/* 向下走 */
				OffSetX = 1, OffSetY = 0;
				break;
			case 'a':
			case 'A':
				OffSetY = -1, OffSetX = 0;/* 向左走 */
				break;
			case 'd':
			case 'D':
				OffSetY = 1, OffSetX = 0;
				break;
			case 'z':
			case 'Z':/* 撤销 */
				if (bFlag)
				{/* 带箱子撤销, */
					Map[level][PosX + OffSetX][PosY + OffSetY] -= 3;//
					Map[level][PosX][PosY] += 3 - 2;
					Map[level][PosX - OffSetX][PosY - OffSetY] += 2;
				}
				else
				{/* 不带箱子撤销 */
					Map[level][PosX][PosY] -= 2;
					Map[level][PosX - OffSetX][PosY - OffSetY] += 2;
				}
				PosX -= OffSetX, PosY -= OffSetY;//必须将人的位置更新
				OffSetX = 0, OffSetY = 0;/* 防止他推许多步,只能退一步 */
				bFlag = false;
				break;
			case 'r':
			case 'R':
				cout << "确定重玩吗?y\/n\n";
				int sInput = _getch();
				if ('y'== sInput || 'Y' == sInput)
				{
					memcpy(Map[level], MapBuffer, sizeof(Map[level]));
				}

			}
			/* 移动 */
			if (0 == Map[level][PosX + OffSetX][PosY + OffSetY] || 4 == Map[level][PosX + OffSetX][PosY + OffSetY])
			{/* 根据人是可以移动 ,在没有推动箱子的情况下 */
				bFlag = false;//必须加,否则下个判断的对这个作用域影响
				Map[level][PosX + OffSetX][PosY + OffSetY] += 2;
				Map[level][PosX][PosY] -= 2;
				PosX += OffSetX, PosY += OffSetY;
			}
			else if(3 == Map[level][PosX + OffSetX][PosY + OffSetY] || 7 == Map[level][PosX + OffSetX][PosY + OffSetY])
			{/* 根据人是可以推动箱子 ,在推动箱子的情况下 7为 */
				if (0 == Map[level][PosX + OffSetX * 2][PosY + OffSetY * 2] || 4 == Map[level][PosX + OffSetX*2][PosY + OffSetY*2])
				{/* 根据推箱子下一方向,判断是否走得通 [PosX + OffSetX * 2][PosY + OffSetY * 2] 代表箱子的下一个方向 */
					bFlag = true;
					Map[level][PosX + OffSetX * 2][PosY + OffSetY * 2] += 3;//将箱子的下一个方向设置为箱子
					Map[level][PosX + OffSetX][PosY + OffSetY] += -3 + 2;//减去箱子,变成通路,通路+2代表人
					Map[level][PosX][PosY] -= 2;
					PosX += OffSetX, PosY += OffSetY;
					if (7 == Map[level][PosX + OffSetX][PosY + OffSetY])
					{/* 判断是否赢了*/
						Success++;
						if (numberSuccess == Success)
						{
							cout << "你赢了" << endl;
							break;
						}
						
					}
				}
			}
			//打印地图
		}//while
		system("cls");
	}//for level
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值