今天给大家介绍传统扫雷游戏的制作思路吧,为什么选择这个游戏呢?
1.它太金典了,金典到我们都知道,都玩过,都会玩;
2.它也是一个轻量级的小游戏,比较简单。
我们先来捋一下扫雷游戏中的要素:
从上到下的UI:遮罩层——>雷层——>数字层——>底层背景层。
下面来介绍一下制作流程:
1.我们制作的时候需要从底层开始做起,首先是底层背景层,只需要一张图片就ok了,作为游戏的背景;
2.按道理来水,我们应该接下来做数字显示层。可能有些朋友和我一样,一开始认为是先把数字标好再去布雷,其实应该是先布雷,再根据布雷情况给每个格子标数字,所以我们接下来是做雷层。
在这里提供给大家最简单的布雷思路:遍历nm个格子,每个格子随机指定是否是雷。为了不让生成雷的概率过大,我们可以根据概率来决定是否生成雷。
3.生成每个格子的遮罩层:遍历nm个格子,分别创建一个Button。
4.根据玩家点击的格子位置,判断周围8个格子雷的数量显示数字。
现在我就来剖析一下扫雷的制作思路:
1.创建地图,并随机生成雷
在这里我们创建一个m*n的地图,用二维数组存储地图信息,0代表无雷,1代表又雷。由于ts不能直接使用二维数组,需要借助一维数组帮助,使用方法如下:
let arr = new Array();
for (let i = 0; i < m; i++)
{
arr[i] = new Array();
for (let j = 0; j < n; j++)
{
let num;//num=0或num=-1
arr[i][j] = num;
}
}
2.判断当前点击的是否是雷。
在玩家点击了一个i格子时,我们需要判断接下来游戏的状态:
1.如果不是雷,则计算该格子周围雷的个数。我们需要计算格子周围8个数中雷的个数,显示在当前格子上。 如下图:
//不是炸弹,创建数字
else {
if (evt.currentTarget.x - this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y - this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x - this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x - this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y + this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x == this.bowContainer.getChildAt(i).x && evt.currentTarget.y - this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x == this.bowContainer.getChildAt(i).x && evt.currentTarget.y + this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x + this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y - this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x + this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
if (evt.currentTarget.x + this.currentCellW == this.bowContainer.getChildAt(i).x && evt.currentTarget.y + this.currentCellH == this.bowContainer.getChildAt(i).y) { this.bowNum++; }
}
textNum.text = this.bowNum.toString();
2.如果是雷,则显示所有雷,游戏失败。在第一步生成地图的时候我们顺便也应该生成雷,这时候我们比较友好的做法是把所有的雷装进一个雷的数组,方便这里失败时的显示。
///点击某个方格后显示对应信息
//遍历雷,看当前对象是否是雷
for (var i = 0; i < this.bowContainer.numChildren; i++) {
//如果是雷,显示所有雷
if (evt.currentTarget.x == this.bowContainer.getChildAt(i).x && evt.currentTarget.y == this.bowContainer.getChildAt(i).y) {
this.gamePanel.addChildAt(this.bowContainer, 4);
this.failM.play(0, 1);
//地图上所有按钮不可点击
this.lockAllBtn();
this.showBannerAd("adunit-4a5e80c193902450");
// this.showVideoAd("adunit-4ad7c6693898c4b0", this.VideoAdSuccess, this.VideoAdfail);
break;
}
3.自动展开无雷区域
先给大家讲讲标题的含义。即当前点击的格子不是雷,寻找周围的8个格子,如果8个格子中其中至少有一个不存在雷,找到该种格子,继续寻找周围8个格子判断是否存在不为雷的。如此反复迭代
上述方法采用的是迭代递归的思想,其实该方法效率并不高,但作为初学者我们能实现此功能就ok了。
4.胜利判断
就差最后一步了,当然是判断胜利了,其实方法很简单,只需要判断剩下未点击的格子数是否等于雷的个数。
扫雷的算法就介绍给大家了,这个算法是我第一次做扫雷时候使用的,可能不是特别完美,有什么建议或意见的,大家可以在下方留言哦!
像是生活中的任何事情一样,只有通过汗水和时间,才能精通于编程。编程技巧与其他技巧没有什么不同,投入 10000 小时之后,你也可以成为程序界的大佬
这段时间我在寻找新坑,我们公司有个坑一直没人做,也就是动态 flutter,支持热更新,支持预加载,支持分布式开发
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!