vue学习,制作扫雷游戏

准备工作

引入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>

运行效果图

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值