准备工作
引入vue.js
<!-- cdn方式,调用vue的官方js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
html、css
<div id="app">
<h4></h4>
<button >重新开始</button>
<table id="tb">
<tr>
<td class="unit"></td>
</tr>
</table>
</div>
<style>
*{
margin: 0;
padding: 0;
}
h4{
margin: 10px;
text-align: center;
}
table{
margin: 0 auto;
margin-top: 50px;
padding: 10px;
border: 1px solid #000000;
border-radius: 5px;
}
.unit{
cursor:pointer;
width: 30px;
height: 30px;
text-align: center;
background-color: black;
}
button{
display: block;
margin: 0 auto;
padding: 10px;
}
</style>
游戏完整代码(附详细注释)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>果汁扫雷</title>
<!-- author: gz -->
<!-- cdn方式,调用vue的官方js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-text 属性表示标签的内容与innerHTML类似但会以纯文本方式显示 不解析;
相似的vue属性还有v-html 里面可以放入并解析html标签内容 -->
<h4 v-text="'score: ' + score + ' —— your time:'+m_time"></h4>
<!-- @click => v-on:click ; v-on 是vue中用于事件绑定的属性,
可以将html的标签事件与自定义的方法绑定起来 -->
<button @click="reset" v-if="gameOver" >重新开始</button>
<table id="tb">
<!-- v-for 类似c语言中 for 循环,语法更加易懂; :key => v-bind:key, 其中index是列表的序号 从0开始 -->
<tr v-for="(item, index) in gameMap" :key="index" >
<!-- onselectstart 属性是为了文本不被选中; vue的标签语法中是可以使用表达式的, 这里使用的是三目运算符 -->
<td onselectstart="return false;" v-for="(m_item, m_index) in item" class="unit" :style="(gameOver && gameMap[index][m_index] >= 0)?'background-color:red':''"
@click="handle(index, m_index)" v-text="gameOver ? gameMap[index][m_index]:''"></td>
</tr>
</table>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
map_width:30, /* 地图宽*/
map_height:15,/* 地图高 */
gameMap:[], /* 地图 ,数值为 -1 表示*/
gameMap_click:[], /* 地图点击的记录 */
gameOver:false,/* 游戏结束标志 */
score:0, /* 分数*/
m_time:0 /* 计时*/
},
created() {
/* 创建30行,15列的地图map, gameMap 采用随机数赋值,地雷则置为-1,否则置为0; gameMap_click 默认值为false */
for(i = 0; i < this.map_height; i ++){
var tmp_list = []
var tmp_list2 = []
for(j = 0; j < this.map_width; j ++){
tmp_list.push(Math.random()>0.8?-1:0)
tmp_list2.push(false)
}
this.gameMap.push(tmp_list)
this.gameMap_click.push(tmp_list2)
}
/* 为地图赋值 */
for(i = 0; i < this.map_height; i ++){
for(j = 0; j < this.map_width; j ++){
if(this.gameMap[i][j] != -1){
this.gameMap[i][j] = this.scan_arround(i, j)
}
}
}
/* 计时器 */
window.setInterval(function () {
vm.$data.m_time++
}, 1000)
},
methods:{
/* 重新开始游戏的按钮 */
reset(){
window.location.reload()
},
/* 扫描 (i,j) 这个点四周有多少地雷 */
scan_arround(i, j){
count = 0
if(i - 1 >= 0 && this.gameMap[i-1][j] == -1) count++
if(j - 1 >= 0 && this.gameMap[i][j-1] == -1) count ++
if(i + 1 < this.map_height && this.gameMap[i+1][j] == -1) count ++
if(j + 1 < this.map_width && this.gameMap[i][j+1] == -1) count ++
if(j - 1 >= 0 && i - 1 >= 0 && this.gameMap[i - 1][j-1] == -1) count ++
if(j + 1 < this.map_width && i + 1 < this.map_height && this.gameMap[i + 1][j + 1] == -1) count ++
if(j - 1 >= 0 && i + 1 < this.map_height && this.gameMap[i + 1][j - 1] == -1) count ++
if(j + 1 < this.map_width && i - 1 >= 0 && this.gameMap[i - 1][j + 1] == -1) count ++
return count
},
/* 方块点击函数 */
handle(i, j){
/* 如果游戏结束将不可点击 */
if(this.gameOver) return
/* 获取点击的方块:-------------- table|------ tbody|---------- tr|-----------td */
target = document.getElementById("tb").childNodes[0].childNodes[i].childNodes[j]
target.innerHTML = this.gameMap[i][j]
if(this.gameMap[i][j] == '-1'){
this.gameOver = true
}else{
this.auto_scan(i, j)
}
},
/* 上下左右:1,2,3,4 0:四周 */
auto_scan(i, j){
if(i<0 || i >= this.map_height) return
if(j < 0 || j >= this.map_width ) return
if(this.gameMap[i][j] == -1 ) return
if(this.gameMap_click[i][j]) return
target = document.getElementById("tb").childNodes[0].childNodes[i].childNodes[j]
/* 设置该方块为已点击 */
this.gameMap_click[i][j] = true
target.innerHTML = this.gameMap[i][j]
/* 设置该方块为红色 */
target.style.backgroundColor = "red"
/* 分数加一 */
this.score ++
/* 如果当前的方块数值不为0,则不进行扩散 */
if(this.gameMap[i][j] != 0 ) return
/* 递归扩散 */
this.auto_scan(i + 1, j)
this.auto_scan(i - 1, j)
this.auto_scan(i, j + 1)
this.auto_scan(i, j - 1)
this.auto_scan(i + 1, j + 1)
this.auto_scan(i - 1, j + 1)
this.auto_scan(i + 1, j - 1)
this.auto_scan(i - 1, j - 1)
}
}
})
</script>
<style>
*{
margin: 0;
padding: 0;
}
h4{
margin: 10px;
text-align: center;
}
table{
margin: 0 auto;
margin-top: 50px;
padding: 10px;
border: 1px solid #000000;
border-radius: 5px;
}
.unit{
cursor:pointer;
width: 30px;
height: 30px;
text-align: center;
background-color: black;
}
button{
display: block;
margin: 0 auto;
padding: 10px;
}
</style>
</html>
运行效果图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/65ddcc814bf0987bbbe525d5887a653c.png)