教你用C/C++写推箱子---简单易懂图片版

闲话先不多说,先来看看成品吧!


  1. 成品展示

人物向左
人物向上


怎么样?我相信看到这里的你肯定想继续看下去,那就闲话不多说,开始学习吧!


分析

我们面临的问题

1. 地图怎么表示?

无非有以下几种:

箱子
已推好的箱子
目的地

解决思路

墙可以用0表示,路用1表示,目的地用2表示,箱子用3表示,人的价值用5表示,已推好的箱子应该是2+2=4(原谅我想再加一个等号);

其实啊!这样做是有道理的

为什么?
请听我分析
路用1表示没问题,目的地的话用2表示其实就相当于在路的上面再加了1,目的地价值是1,这里其实意义并不大。关键对于后面的数据影响很大,这样可以简化很多东西。
箱子、人都是可以动的,我们可以只用一个整形二维数组来表示:

map[maxn][maxm]

箱子在某个地方(坐标),其实他的值应该是路的价值加上箱子的价值,其实箱子价值为2,又因为人的价值为5,所以,地图其实只可能有以下值:

0(墙) 1(路)2(目的地——还可能是箱子在墙上,可以避免) 3(箱子在路上)
4(已推好的箱子,即箱子在目的地上)
6(人站在路上——也可能是在路上的箱子加箱子在路上,可以避免)
7(人站在目的地上——也可能是在路上的箱子加箱子在目的地上,可以避免)
8(人加箱子加路,可能暂时不合法)
9(人加箱子加路加目的地的价值,可能暂时不合法)

现在,聪明的你懂了为什么要这样做吧! -_-

因为,这样表示就可以只用一个二维数组表示所有
判断是否完成:

只需要扫描二维数组的值是否还有3,没有了就说明完成了

2. 怎么推?

相信现在的你对地图为什么这样表示可能还是存在困惑,没关系,现在我们一起来了解一下:

无非是:

往上推 往下推 往左推 往右推

那么我们就可以获取玩家的输入上下左右指令

提示:

通过_getch()函数获取指令
上的ASCII值是72
下的ASCII值是80
左的ASCII值是75
右的ASCII值是77


好我们言归正传: 无论往哪个方向推,都需要面对一下几种情况:

1:是否是有效指令?
2:假如是有效指令,相应位置数据该怎样变化?

第一种好判断,只需要检查推过去数据是否是5,或者,下一位置是3、4,但再下一个位置的值是0、3、4,这两种指令都为无效指令,应不做反应(不理他,心情好写个温馨提示提醒他)。为什么这样说呢?是否会想到什么?
是的,我们之前的数据表示方法在这里帮了我们大忙
并且,从侧面也说明我们的推法:

对应位置的值的加减

假如是往下推:
对应位置的值加5,原来位置减5,并对对应位置的值进行判断
如果值是8,9,说明该位置原来是箱子-_- ,于是,再接着判断下一步,如果下一步的值是1或2,而不是0,3,4,那我们应该做什么呢?
-_- ,别想了,人家是合法指令,帮人家推过去吧!
所以,操作如下:
原位置数值减5,下一位置数值加5,然后原位置的下一位置减掉2,原来位置的下一位置的下一位置加2
很简单吧!
其实,这样已经解决了很多问题,如果你把每一步把控好,则不会出现问题 -_-
当然,还有比较简单的情况:
下一位置是1,而不是0、3、4,说明什么?
人在走路
操作如下:
原位置减5,下一位置加5
其他情况就请读者自己照着该思路解决吧!实在不知道欢迎留言,博主会及时回复


3.优化与拓展

相信这样,许多读者已经可以写出来了。那么接下来的便是:

优化与拓展
建议1

可以在类中定义两个坐标X、Y记录人的位置,在C中可以定义两个全局变量X、Y,并且X、Y随着操作而不断刷新,这样下次就可以直接定位了。

建议2

因为推的动作一致,可以抽象成一个函数Push(int x,int y)
签名如此,大家能想到什么吗?
假如是往上推那么x=-1,y=0;
同理只需要一个switch语句,便可以执行操作


拓展

博主的文件

其中,map.txt包含了地图,图片可以更改。路径用相对路径,地图也可以更改,如此便可以更改,反正画图函数只认该位置的数值是几

这是map.txt内容:
博主map.txt文件内容
这样做的好处是显而易见的,可以自行更改,使得可拓展性更好


最后,博主再附上程序及部分素材下载链接
这里写图片描述
谢谢大家的观看

猜你喜欢

转载自blog.csdn.net/Mr_June/article/details/81813058