思考并回答以下问题:
- 请阐述扫雷开发思路。
- 如何拓展扫雷的游戏玩法?
游戏规则
扫雷示意图
扫雷的布局
游戏区包括雷区、地雷计数器(记录剩余地雷数)和计时器(记录游戏时间)。在确定大小的矩形雷区中随机布置一定数量的地雷(初级为9×9个方块10个雷,中级为16×16个方块40个雷,高级为16×30个方块99个雷,自定义级别可以自己设定雷区大小和雷数,但是雷区大小不能超过24×30个方块),玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷。
扫雷的基本操作
游戏的基本操作包括左键单击、右键单击、左右键双击三种。其中左键用于打开安全的格子,推进游戏进度;右键用于标记地雷,以辅助判断,或为接下来的双击做准备;双击在一个数字周围的地雷标记完时,相当于对数字周围未打开的方块均进行一次左键单击操作。
左键单击:在判断出不是雷的方块上按下左键,可以打开该方块。如果方块上出现数字,则该数字表示以该方块为中心的3×3区域中的地雷数。如果方块上为空(相当于0),则可以递归地打开与空相邻的方块;如果不幸触雷,则游戏结束。
图1表示在游戏区中间/边缘/角落点击方块时数字显示地雷数的范围,红点所在处为鼠标左键单击方块。
图1 范围示意图
右键单击:在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。重复一次或两次操作可取消标记(如果在游戏菜单中勾选了“标记(?)”,则需要两次操作来取消标雷)。
左右键双击:同时按下左键和右键完成左右键双击。当双击位置周围已标记雷数等于该位置数字时操作有效,相当于对该数字周围未打开的方块均进行一次左键单击操作。地雷未标记完全时使用双击无效。若数字周围有标错的地雷,则游戏结束,标错的地雷上会显示一个“×”。
游戏结束
当一个地雷被踩中时,所有地雷都将显示,游戏失败;玩家猜出所有地雷,游戏成功。
程序思路
雷区绘制
用于绘制整个雷区,我们可以利用二维数组记录每个方块的位置信息,便于接下来对方块的状态和信息进行存储跟踪。每一个方块都有两个属性:布尔值isMine,用于标记当前方块是否有雷,初始值为false;整型变量NearByMines,用于记录周围的地雷数,初始值为0。
建立雷区后,我们会通过随机数选择其中的某些方块,将它们的isMine值更改为true,同时将与地雷方块相邻的方块的NearByMines值加1。
例如建立以下雷区后,给[1][0]和[1][2]这两个方块赋予地雷,则下列雷区内方块的值将会改变。
左键单击
我们都知道扫雷有三种点击方式,其中左键单击中的算法最为核心。这里需要分两种基本情况讨论。
1.单击到的方块没有雷。
这是扫雷中最核心的部分,这里举一个简单的例子来更好的帮助理解:在用户单击雷区中的方块[1][2]时,我们需要通过递归遍历算法和计数器,检测其周围八个方块([0][1],[0][2],[0][3],[1][1],[1][3],[2][1],[2][2],[2][3])是否有地雷,有几个地雷。当然,在检测前,我们还需要判断这八个方块是否超过雷区边界,超过雷区边界的方块则不需要检测(如点击方块[0][0]时只需遍历方块[0][1],[1][0],[1][1]即可)。
当我们点击到的方块周围八个方块均没有地雷时,则需分别以其周围八个方块为中心继续遍历,直到接近一个附近有地雷的方块后递归停止。其实这段算法用到的就是一个递归函数。1
2
3
4
5
6
7
8
9
10
11遍历函数(方块坐标,是否遍历)
{
If(方块在雷区范围内)
{
If(周围有地雷)
遍历结束;
Else
//这里需要写八个函数语句,对周围八个方块各自都进行遍历
遍历函数(方块坐标,遍历);
}
}
2.单击到的方块存在雷
在用户不慎点击到地雷,我们需要用遍历算法对雷区中所有的方块进行判断,显示地雷,此时游戏结束。
右键单击
对于右键单击,处理起来就比左键单击容易一点了。我们只需获取当前点击的方块数组下标,将其显示的图片加载为红旗即可。当方块显示状态为红旗时,鼠标左键需被禁用,只有再次右键单击取消该状态的时候鼠标左键才能被取消禁用。
左右键双击
左右键双击需判断已经打开的方块上的数字X与X周围八块方块中被标记的方块总数是否相等。若相等,则在X上双击后可打开X周围八个方块中未被标记且未被点击的方块。1
2
3
4
5
6
7
8If(方块数字 == 周围标记总数)
{
遍历周围八个方块
If(标记错误)
遍历加载所有地雷,游戏结束
Else
翻开未翻开的方块
}
游戏结束
如果在玩家点击过程中点到地雷,则通过遍历加载所有地雷,玩家失败,游戏结束。
如果玩家成功,需通过遍历确定所有翻开的方块均无雷,游戏结束,玩家胜利。
游戏流程图
程序实现
1 | using System.Collections; |
1 | using System.Collections; |
1 | public init_script : MonoBehaviour |