![游戏设计与开发:Unity实战完全自学教程](https://wfqqreader-1252317822.image.myqcloud.com/cover/6/43738006/b_43738006.jpg)
3.4.5 洗牌状态的设计与实现
当游戏准备进入等待操作状态时发现没有可以操作的对象,即棋盘上不存在最小可合成的糖果组合,才会进入洗牌(Shuffle)状态。与其相关的算法有两个:最小可合成组合算法和洗牌算法。
1.最小可合成组合算法
最小可合成组合算法的内容是对每个需要检测的形状在棋盘上做比对,遍历整个棋盘,判断是否存在符合条件的组合。如图 3-19 所示,若该棋盘状态正好符合所检测的形状,则说明存在可操作的糖果。否则如图3-20所示,表示该棋盘不符合所检测的形状。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_78_1.jpg?sign=1739592800-fuV5PgrZu0H8YHRX1HUdQFtOOUNRvdKD-0-27c64a36dbbe8e225f53aabbd033d810)
图3-19
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_78_2.jpg?sign=1739592800-q5UETwtnhOXoAD2saNhvC84eagKeU1qv-0-0faa6e87ec7525a12967aa0a44df0ac6)
图3-20
该游戏将这部分的功能都集中到一个单独的类中,该类不继承MonoBehaviour。新建一个空白脚本,将其命名为“PatternCheck”,双击打开该脚本,将继承的代码删除,做成一个独立的类。接下来在该类中实现最小可合成组合算法相关的内容。
为了实现这一算法,首先需要定义检测的形状,对同一形状的检测需要每个方向都检测一次,即每旋转90度检测一次。最后有一个用于返回检测结果的方法,其分为两部分,分别为:检测形状初始化方法和全盘扫描检测方法。
(1)检测形状初始化方法
检测形状初始化方法需要使用一个添加形状的接口,通过在GameManager.cs脚本中调用这个接口来实现形状的添加初始化。通过在二维数组中填写“0”和“1”来表示形状的组成,填写“1”的部分表示相同的颜色,填写“0”的部分表示任意颜色。具体代码如下。
代码位置:见源代码目录下Assets\Scripts\PatternCheck.cs。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_78_3.jpg?sign=1739592800-eh3MlNunmjOvAhrRKm9ANUdSLSFNkXYy-0-f03a3ae8bc9b25daca0a34ebcc1c7124)
在GameManager.cs脚本中通过调用Add方法来添加初始形状,其代码如下。
代码位置:见源代码目录下Assets\Scripts\GameManager.cs。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_79_1.jpg?sign=1739592800-ieKRi3YqKYHhTJLaFA3MUaXSjsaTACY0-0-1e4a2522dc16ae8c3c96c56087c45a70)
在棋盘中查找某种形状时,需要对每个格子进行比较。具体做法是:
① 先把匹配图放在棋盘左下角或者左上角,比较形状是否匹配。
② 往右移动一格,再比较一次。
③ 不断把形状往右移动一格,尝试匹配,直到遇到右边界时往回移动到下一行最左边,再次重复上述操作。
思考并理解这一过程,我们可以定义一个概念“偏移量”来表示形状在棋盘上的位置,偏移量从(0,0)开始,到棋盘边界结束,不断将棋盘上的糖果与形状进行比较。最终找到可以通过操作删除的形状。
为了用程序实现这一思路,还需要设计一个嵌套的数据类型,用于保存所有的形状。此数据类型可以设计为List<Vector2Int[]>,一系列形状的数据结构如表3-4所示。从表3-4可以看出,外层数据类型中包含了多个形状的数据,每个形状又是由多个坐标值构成的。
表3-4
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_79_2.jpg?sign=1739592800-nKHOESpu8FG3Q7KHvxEP01PG6Dl7XqzU-0-2fb4363cb6013491a1596c1da4da6d5a)
这些数据需要在获取到初始形状后进行设置,在该游戏中,是在GameManager.cs 脚本中添加初始形状后调用SetPosition方法进行设置的,相关代码如下。
代码位置:见源代码目录下Assets\Scripts\PatternCheck.cs。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_79_3.jpg?sign=1739592800-ZxvMaczho2mdM0OaXYMqseOQPS2JOHeT-0-95f6149b2612b8bb6c65378d5f905904)
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_80_1.jpg?sign=1739592800-MqQgaEcrb70oCfMtE8eMfKS1lzNTN3Nb-0-fd6fa75144d82571bb983ff20fa4c3df)
注意:不仅要保存每个形状,还需要保存该形状旋转90度、180度、270度以后的形状。
(2)全盘扫描检测方法
有了前文代码中的图形列表,才能检测棋盘是否存在可操作的行为,该方法名为“CheckPattern-ByPosition”(全盘扫描检测),该方法及相关代码如下。
代码位置:见源代码目录下Assets\Scripts\PatternCheck.cs。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_80_2.jpg?sign=1739592800-XiPV84R2gJWrsUtqM9aRRiwcp5kgft1e-0-61f0839d49ecfc9c9f4f8815d8d0732c)
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_81_1.jpg?sign=1739592800-6flCAirZW9vobGWEERUTcKwsZGIxlDyz-0-a6819893370e541ad563f92e246d27c0)
2.洗牌算法
洗牌算法的内容是从左到右、从上到下遍历整个棋盘,并把每个格子的糖果和该格子之后某个格子中的糖果交换。相关代码如下。
代码位置:见源代码目录下Assets\Scripts\GameManager.cs。
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_81_2.jpg?sign=1739592800-0r7XyiVMIRfXNIR6uMYKHgb5k3MRcJfi-0-fc231c01ec1e2d2eb37dd4f2a9177ea5)
![](https://epubservercos.yuewen.com/9A2E4E/23020637701641706/epubprivate/OEBPS/Images/42155_82_1.jpg?sign=1739592800-uShqt99aNsVOkBY0IREkqCSGyJGnJq9O-0-2f967c31d3eaca9f4834a55f025e3bc1)
至此,洗牌状态相关的代码实现已经全部讲解完毕。因篇幅有限,无法展示所有的细节内容,有不清楚的地方请读者翻阅本实例的源代码。