前几天做一个简单的迷宫游戏,在网上找了不少的资料,现在自己总结一下基本的思路,以便往后能使用。
做这个迷宫游戏,首先当然要生成迷宫图,我把它分为三个步骤:
(1)先画一个小盒子,有四扇墙(可以用数组来表示),上下左右,画一个小盒子的时候先判断上下左右是否有墙,然后再用画笔画出来。
(2)把小盒子堆成一个表格形式,有M行N列,每个小格子就是一个单元格。在这里设置一个入口,一个出口,即把靠边的两个单元格的一扇墙开通。
(3)这是最关键的一步,如何随机生成迷宫的通道。首先随机选取一个小盒子为当前访问单元格,如果它没有被访问过则把它标志为已访问,接下来找出其上下左右没有被访问过的小盒子,在相邻的小盒子随机选取一个并把它们之间的墙拆掉(比如说随机选取的是左邻的小盒子,把当前访问的小盒子的左墙拆除,左邻的小盒子的右墙拆除),这样两个小盒子之间就有了通道。再往下一步就把选取相邻的小盒子为当然访问单元格,继续前面的步骤。这里漏了一个问题,当前访问的单元格相邻的小盒子都被访问过,这种情况就随机选取一个被访问过的小盒子作为当前访问的单元格,重复前面的步骤,直接到所有的小盒子都被访问过。或许还有一个疑问,为什么这样就会存在一条迷宫通路呢?按前面所讲的算法,每个小盒子至少与一个相邻的小盒子有打开通道,即所有的小盒子都不会独立,因此任意两小盒子尽然会存在一条通路。
有了前面的迷宫图,接下来就是如何让一个小东西(设置一个小圆)在里面走动。
这会遇到以下几中问题:
1、如何让小圆动起来,通过键盘控制方向。小圆有半径,有圆心,始点坐标(因为是通过g.drawOval(int x,int y,int width, int height)实现画圆)。既然是通过键盘方向来控制,当然就要添加KeyListener,当按TOP键,始点的Y轴坐就减去一个单位(这个单位可以控制走动的速度),X轴不变,圆心保持一致,再画一次小圆,就样就可以看得到小圆向上前进一步,但这也会有一个问题,前一步那个小圆的痕迹如何处理,这里使用g.clearRect来清理(它是用当前的背景色来覆盖你所选择的区域),不过必需知道小圆前一步的始点坐标,记录也很容易,只要判断小圆行走的方向,在相应的位置做运算就OK。
2、小圆在没有墙的情况下可以行走,遇到墙的时候就止步。
把问题看作缩放一个小盒子来分析,小圆在一个小盒子可以有哪些动作,
如图: (左右下都有墙,上边无墙)小圆的边界没有越过墙或者是行走的方向上没有墙,这两情况小圆都可以走动。具体怎么判断,因为是这些图都是用
Graphics 来画,我们很容易得到墙的X轴,或是Y轴坐标,而小圆的圆心坐标已有记录,通过小圆的始坐标可以得知小圆所在盒子的行号与列号,因此可以判断小圆与当前盒子的墙位置关系。如果不能行走即是始点坐标保待不变。
3、小圆在一扇墙中间时不能行走。
这个问题比较来表述,通过图比较容易理解,
如果小圆向左走会发生什么情况,结果是左边的墙会被画成黑色,这当然不是合法的操作,这种情况我只需要判断小圆的边界有没有超出当前小盒子的边界,即整个小圆必需在当前的小盒子中,有图中,小圆向左走动,下边界明显不在当前的小盒子中,因此不能让这个动作发生
4,小圆不能超出整个迷宫图的边界
程序运行界面:
小结:
实现这种迷宫不会难,很多东西都是细心问题,我就精心大意,把行与列反过来,结果生成很奇怪的迷宫图,我寻根问底,怎么看都不会有错,当时我怒了,晚上拿着篮球就往球场跑去,还好是自己一个人。