【程序猿】手把手教你做3D扫雷:完结篇
在这个系列的最后,我们将实现扫雷游戏点击网格功能,让我们的游戏更具可玩性。我们还要实现玩家能够赢得或输掉游戏的功能。如果你完成之前的教程,游戏现在应该就能够创建格子的区域,然后随机地把炸弹赋值给他们。当玩家用鼠标在格子上划过就会出现高亮效果,还能够放置和移除旗子。每个格子之间还能够通信,还能够计算出附近的炸弹数。
我们已经添加了右键点击防止旗子的功能,现在,让我们添加左键揭开格子的功能。在OnMouseOver函数中,我们需要引用鼠标左击的方法。代码如下:
当鼠标左键点击时,UncoverTile函数将被调用。确保你创建了这个方法,这样才不会出Bug!
如果运行成功了,我们需要声明一个新的材质。
创建区别于基础色的颜色。就比如你的基础色为蓝色,你就应该选择绿色代表已经揭开的状态。千万别选择红色,因为接下来我们会用这个颜色表示揭开炸弹后的状态。当我们调用这个函数后,会发生如下事情:
· 第一步会检查格子是否确实有炸弹;
· 如果没有炸弹,这个区域便会被设置为uncovered状态,激活文本显示状态,向我们显示周围炸弹数,然后设置uncovered材质;
· 接着,格子不能够被点击第二次,也不会重复高亮,这就意味着格子响应事件只会在鼠标真正点击之后发生。
在我们运行测试前,我们需要确保当鼠标滑过并离开格子后材质不会被改变。为了实现这个,我们需要调整OnMouseExit函数,如下:
这样,如果格子没有被揭开,颜色只会变成黑色。试一下呗!你应该能揭开格子了。现在,即便格子上有炸弹,也不会有反应。
这是个难题。在扫雷游戏中,当你揭开一个格子时,挨着的空的格子就会被间接揭开,然后接着传开。这里考虑一下:
事实上我们看不到炸弹和数字,只有平常的格子:
当一个周围炸弹数为0的格子被揭开后,其周围的格子你会被自动揭开,然后传递给周围的格子。
新揭开的格子会检测他们周围的格子信息,如果周围的格子也没有炸弹,也会被自动揭开。
这样的传递会像波一样传递,直到临近的格子有炸弹才会停止传递。
这就能实现扫雷中出现的空白区域的情况。为了能够实现这一功能,我们需要两个方法:UncoverAdjacentTile和UncoverTileExternal。
我们还得更新一下UncoverTile函数:
当我们揭开一个格子,临近的格子中并没有炸弹,就会调用UncoverAdjacentTiles函数。然后就会检测附近的各自看看有没有炸弹。如果还是没有,就会自动揭开格子,然后进入下一轮的检测。如果附近有炸弹,就会只揭开当前的格子。我们需要进行小测试:为了能够容易出现空白区域,我们创建一个很大的区域9x9的81格子的游戏区域,这里只放置10个炸弹。
现在游戏就可以运行了,当然现在还不能触发炸弹,这个功能之后会实现的。
当我们揭开有炸弹的格子时,游戏就会结束,玩家也会输掉游戏。并且,其他所有的炸弹也会显示出来。为了实现这种效果,我们需要添加一个新的材质来表示爆炸的炸弹:
反正我建议使用红色表示炸弹爆炸。我们还需要另外两个方法去处理所有炸弹爆炸的效果:
我们在UncoverTile函数中调用上面两个方法:
如果格子内有炸弹,格子便会爆炸。Explode函数会发送“explode”给其他所有的炸弹,并且引爆他们。
当所有含炸弹的格子被正确地标定好旗子后,游戏便胜利了。这时候,那些没有被揭开的格子也会被自动揭开。那么我们怎么才能检测到这些?
让我们先在Grid类中添加一个state变量,这样我们才能检测到游戏目前的状态(游戏中,输了,赢了)。
当我们处在某个游戏状态时,我们可以创建一个简单的GUI来呈现在屏幕上这些信息。我们可以用原生的GUI。
这个会告诉我们当前游戏所处状态,我们将这些状态分为inGame,gameOver和gameWon。我们也可以在Tile中检测,实现只有当前游戏状态为inGame后格子才能够响应。在OnMouseOver和OnMouseExit函数中,移除所有代码到一个if条件的代码块中,其判断条件为Grid.state是否为inGame,就像这样:
这里有两种方法检测游戏胜利:1.我们可以计算正确标记的炸弹的数量;2.我们还可以检测没有炸弹的格子是不是全都被揭开了。为了实现这个功能,我们需要一下变量,将他们添加到Grid类中:
别忘了在Start函数中将minesRemaining赋值给numberOfMines,其他的变量为0.Start函数如下:
最后一行设置了游戏的状态(这个在之后讲解restart函数中非常重要)。之后我们我们会在Update函数中检测游戏结束的条件:
我们可以通过改变状态为gameWon来结束游戏,揭开所有的格子,并且标记所有剩下的炸弹:
如果上面一切运行正常,我们还需要改下UncoverTile函数,如下:
UncoverTileExternal函数如下:
我们还需要根据旗子是否被准确放置,来调整minesMarkedCorrextly和minesRemaining的值:
同样,我们还要设置输掉游戏的情况。我们可以在Explode函数中实现这个,在Explode添加如下代码:
当这个代码运行时,游戏的状态就转变成了gameOver,格子就不会再响应了:
之前的步骤中我们用了UGUI来告诉玩家他们当前所处的游戏状态。现在我们要扩展来展示更多信息。代码如下:
随着状态的改变,相应的信息就会在屏幕上显示出来。如果输掉游戏或者胜利,我们就能显示如下信息:
我们也可以显示被发现的炸弹数量,或者添加一个重置按钮:当游戏结束后,重新开始游戏。
你可以测试下最终版的扫雷!
就这些了,我们就用Unity创建了一个属于你自己的扫雷游戏。我希望您能够喜欢这个教程,如果有任何问题,请在下面评论区留言。
腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)
……
添加小编微信,发送“程序”
即可直接加入GAD程序猿交流基地
获取行业干货资讯,观看大牛分享直播
↓长按添加小编GAD-沫沫↓