小时候玩的经典扫雷游戏你还记得吗?
一、游戏设定
可以通过游戏设置来设置扫雷区域的大小和埋雷的数量。
游戏规则比较灵活,可以比谁先扫到第一颗雷,也可以比谁先找出所有的雷。
先睹为快:
二、逻辑实现
核心的逻辑是扫雷区域中雷的随机摆放,实现这个逻辑有这么几步。
- 随机生成雷的坐标
注意判断不能超出区域。
createRandPosition() {
let x = Math.round(Math.random() * (this.size - 1));
let y = Math.round(Math.random() * (this.size - 1));
return [x, y];
}
- 保存所有雷的坐标
注意判断不能出现重复。
setMinePosition() {
let position = this.createRandPosition();
let hasPosition = false;
for (let p = 0; p < this.minePosition.length; p++) {
if (this.minePosition[p].toString() == position.toString()) {
hasPosition = true;
}
}
if (!hasPosition && this.minePosition.length < this.mineSize) {
this.minePosition.push(position);
}
if (this.minePosition.length < this.mineSize) {
this.setMinePosition();
}
}
- 初始化区域并布雷
这里的思路是使用 HTML table 生成指定大小的表格,先以行开始,再输出列,这样就会有交叉点,交叉点刚好可以对应雷的位置,比如其中某个雷的位置是 [2, 3] ,那么在渲染 table 的第三行第四列(索引从 0 开始)时就应该布下这个雷。
setArea() {
// 循环行
for (let i = 0; i < this.size; i++) {
// 此行的列
let td = [];
for (let j = 0; j < this.size; j++) {
// 列属性
var tdItems = {};
// 是否是雷,默认不是
tdItems.ismine = 0;
// 循环所有雷的坐标
for (let n = 0; n < this.minePosition.length; n++) {
// 是否符合当前行和当前列
if (this.minePosition[n][0] == i && this.minePosition[n][1] == j) {
// 如果符合,则设为雷
tdItems.ismine = 1;
}
}
// 此点的消除状态,默认未消除
tdItems.isClear = 0;
td.push(tdItems);
}
this.tableData.push(td);
}
}
<table cellspacing="1">
<tr v-for="(tr, trIndex) in tableData">
<td v-for="(td, tdIndex) in tr"
:data-ismine="td.ismine"
:data-isClear="td.isClear"
@click="doClear($event, trIndex, tdIndex)"
:class=" td.isClear == 0 ? 'td-normal' : 'td-clear' ">
<div class="boom" v-if="td.ismine == 1"></div>
</td>
</tr>
</table>
开始扫雷,扫雷就是一个一个的点击事件,点击到这个单元格的时候,通过判断其属性是否是雷即可,然后做相应的数据修改。
// 扫雷事件
doClear(e, trIndex, tdIndex) {
// 当前点击的块是否已经清除
let clearStatus = e.target.dataset.isclear;
// 当前点击的块是否是雷
let clickResult = e.target.dataset.ismine;
// 将当前点击的块的清除状态改为已清除
this.tableData[trIndex][tdIndex].isClear = 1;
// 如果点击的块是未清除状态
if (clearStatus == 0) {
// 如果已清除数量小于总数量,则清除数量加 1
if (this.clearNum < this.size * this.size) {
this.clearNum++;
}
// 如果点到的是雷
if (clickResult == 1) {
// 如果已清除的雷数小于总雷数
if (this.clearMineNum < this.mineSize) {
this.clearMineNum++;
}
alert('你遇到了一颗雷!');
return false;
}
// 如果总数量减去雷的数量等于已清除数量
if (this.size * this.size - this.mineSize == this.clearNum) {
alert('你避开了所有的雷!');
return false;
}
}
}
其它逻辑比较简单,可以参考代码片段。
转载自:https://juejin.cn/post/7145055266734604296