本文实例为大家分享了微信小程序实现扫雷游戏的具体代码,供大家参考,具体内容如下
实验小提醒,打开微信小程序模板时,一定要看清楚,要选js模板,不要选ts模板,因为ts中对数据类型检查更严格,同样的代码在ts中可能无法运行!
实验内容:
编写如下扫雷游戏,基本要求如下:
(1)方块数为10行7列;
(2)有游戏计时(计时单位为秒);
(3)有一个“开始游戏”按钮,按该按钮能重新开始一局游戏。
可依据个人能力自由发挥点:
(1)让玩家可以自由设定方块数;
(2)让玩家可以自由设定地雷数;
实验效果:
程序优势:
1、必须点击开始游戏,才能点击方块,避免用户误碰影响玩的体验
2、游戏玩到中途,可以新开一局,也可以在点击新开一局后,点击取消,继续玩
3、可以点击设置,设置行数,列数或者地雷数任意一个参数,游戏怎么玩儿,由你定
代码目录:
这里面index目录下面四个文件,放的是扫雷相关的代码; 而setUp目录中的四个文件放的是设置页面相关的代码!
实验代码:
index目录下的代码文件
index.wxml
<!--index.wxml--> | |
<view class="time"> | |
<view class="using-time">当前用时:{{timeformat}}</view> | |
<view class="start-game" bindtap="start"> 开始游戏 </view> | |
</view> | |
<view bindtap="setUp" class="set-up">设置</view> | |
<view class="main"> | |
<view wx:for="{{bts}}" wx:for-item="itemRow" class="yy"> | |
<view wx:for="{{itemRow}}" wx:for-item="bt" class="xx" id="{{bt.id}}" style="background-color:{{bt.bgcolor}};color:{{bt.ftcolor}}" bindtap="click"> | |
{{bt.text}} | |
</view> | |
</view> | |
</view> |
index.js
Page({ | |
data: { | |
bts: null, //9*6数组 54个方块,根方块有关的属性全部存储起来 | |
timer:null, | |
hour:0, | |
minute:0, | |
second:0, | |
timeformat:'00:00:00', | |
clickButton:false, | |
cancelButton:false | |
}, | |
start:function(){ | |
var that=this | |
clearInterval(that.data.timer); | |
wx.showModal({ | |
title:'提示', | |
content:'开始游戏', | |
showCancel:true, | |
如何让用户点击取消按钮后,还能继续玩(已解决) | |
success(res){ | |
// 刚开局点击取消后,什么也不做 | |
if(res.cancel ){ | |
if(!that.data.cancelButton){ | |
}else{ | |
that.data.timer = setInterval(that.counter,1000) | |
} | |
// 点击确定后,初始化界面,并回调时间函数 | |
}else{ | |
that.data.cancelButton = true | |
that.init() | |
// clearInterval(this.data.timer) | |
that.data.timer = setInterval(that.counter,1000) | |
that.data.clickButton = true | |
} | |
} | |
}) | |
}, | |
second:'', | |
minute:'', | |
hour:'', | |
counter:function(){ | |
var second = this.data.second | |
var minute = this.data.minute | |
var hour = this.data.hour | |
this.setData({ | |
second:second+1 | |
}) | |
if(second == 60){ | |
this.setData({ | |
second:0, | |
minute:minute+1 | |
}) | |
} | |
if(minute == 60){ | |
this.setData({ | |
minute:0, | |
hour:hour+1 | |
}) | |
} | |
// 下面三个全局变量用于保证时间格式 | |
this.second = second | |
this.minute = minute | |
this.hour = hour | |
if(second < 10){ | |
this.second="0"+second | |
} | |
if(minute < 10){ | |
this.minute = "0"+minute | |
} | |
if(hour < 10){ | |
this.hour="0"+hour | |
} | |
this.setData({ | |
timeformat:this.hour+":"+this.minute+":"+this.second | |
}) | |
}, | |
// 跳转到设置页面的函数 | |
setUp:function () { | |
wx.navigateTo({ | |
url: '../index/setUp/setUpPage', | |
}) | |
// 设置完以后应该重新开始游戏 | |
this.defaultRow = 10 | |
this.defaultColumn = 7 | |
this.defaultDilei = 10 | |
this.init() | |
}, | |
// 设置默认数据,用户不设置也能玩 | |
defaultRow:10, | |
defaultColumn:7, | |
defaultDilei:10, | |
//初始化函数 | |
init: function () { | |
//初始化时间 | |
this.counter() | |
// 下面代码用于获取全局变量数据(只能函数中用) | |
var app = getApp() | |
var setRow = app.globalData.row | |
var setColumn = app.globalData.column | |
var setDilei = app.globalData.dilei | |
this.setData({ | |
hour:0, | |
minute:0, | |
second:0, | |
timeformat:"00"+":"+"00"+":"+"00" | |
}) | |
// 检查用户修改了哪方面数据 | |
if(typeof(setRow) != 'undefined'){ | |
this.defaultRow = setRow | |
} | |
if(typeof(setColumn) != 'undefined'){ | |
this.defaultColumn = setColumn | |
} | |
if(typeof(setDilei) != 'undefined'){ | |
this.defaultDilei = setDilei | |
} | |
//生成指定行和列的方块数组,并初始化 | |
var ds = new Array() | |
for (var i = 0; i <this.defaultRow; i++) { | |
ds[i] = new Array(); | |
for (var j = 0; j < this.defaultColumn; j++) { | |
ds[i][j] = { | |
id: "" + i + j, //方块id | |
bgcolor: "yellow", //方块背景色 | |
ftcolor: "red", //方块文字颜色 | |
text: "", //方块显示的文本信息 | |
dilei: 0 //方块下是否有雷 0:无雷,1有雷 | |
} | |
} | |
} | |
this.data.bts=ds; | |
//随机产生地雷 | |
for (var v = 0; v < this.defaultDilei; v++) { | |
var i = Math.floor(Math.random() * (this.defaultRow-1)) | |
var j = Math.floor(Math.random() * (this.defaultColumn-1)) | |
this.data.bts[i][j].dilei = 1 | |
this.data.bts[i][j].text = "" | |
this.data.bts[i][j].ftcolor = "red" | |
} | |
this.setData({ bts: this.data.bts }) | |
this.data.clickButton = false | |
clearInterval(this.data.timer) | |
}, | |
onLoad: function () { | |
this.counter() | |
this.init() | |
}, | |
countDilei:function(i,j){ | |
var N=0 | |
if(i>0 && j>0) N=N+this.data.bts[i-1][j-1].dilei//左上 | |
if(i>0) N=N+this.data.bts[i-1][j].dilei//上 | |
if(i>0 && j<this.defaultColumn-1) N=N+this.data.bts[i-1][j+1].dilei //右上 | |
if(j>0) N=N+this.data.bts[i][j-1].dilei//左 | |
if(j<this.defaultColumn-1) N=N+this.data.bts[i][j+1].dilei//右 | |
if(i<this.defaultRow-1 && j>0) N=N+this.data.bts[i+1][j-1].dilei | |
if(i<this.defaultRow-1) N=N+this.data.bts[i+1][j].dilei | |
if(i<this.defaultRow-1 && j<this.defaultColumn-1) N=N+this.data.bts[i+1][j+1].dilei | |
return N; | |
}, | |
aotoClick: function (i, j) { | |
var n = this.countDilei(i, j) | |
//无论周围是否有雷都首先将当前翻开,这样递归才可以作为条件判断 | |
this.data.bts[i][j].bgcolor = "white" | |
this.data.bts[i][j].ftcolor = "blue" | |
//再根据周围是否有雷决定是否递归 | |
if (n != 0) { | |
this.data.bts[i][j].text = n | |
}else{//三个条件:存在、未翻开、不是雷 | |
if (i > 0 && j > 0 && this.data.bts[i - 1][j - 1].bgcolor == "yellow" && this.data.bts[i - 1][j - 1].dilei != 1) this.aotoClick(i - 1, j - 1) //左上 | |
if (i > 0 && this.data.bts[i - 1][j].bgcolor == "yellow" && this.data.bts[i - 1][j].dilei != 1) this.aotoClick(i - 1, j) //上 | |
if (i > 0 && j < this.defaultColumn-1 && this.data.bts[i - 1][j + 1].bgcolor == "yellow" && this.data.bts[i - 1][j + 1].dilei != 1) this.aotoClick(i - 1, j + 1) //右上 | |
if (j > 0 && this.data.bts[i][j - 1].bgcolor == "yellow" && this.data.bts[i][j - 1].dilei != 1) this.aotoClick(i, j - 1) //左 | |
if (j < this.defaultColumn-1 && this.data.bts[i][j + 1].bgcolor == "yellow" && this.data.bts[i][j + 1].dilei != 1) this.aotoClick(i, j + 1) //右 | |
if (i < this.defaultRow-1 && j > 0 && this.data.bts[i + 1][j - 1].bgcolor == "yellow" && this.data.bts[i + 1][j - 1].dilei != 1) this.aotoClick(i + 1, j - 1) | |
if (i < this.defaultRow-1 && this.data.bts[i + 1][j].bgcolor == "yellow" && this.data.bts[i + 1][j].dilei != 1) this.aotoClick(i + 1, j) | |
if (i <this.defaultRow-1 && j <this.defaultColumn-1 && this.data.bts[i + 1][j + 1].bgcolor == "yellow" && this.data.bts[i + 1][j + 1].dilei != 1) this.aotoClick(i + 1, j + 1) | |
} | |
} | |
, | |
click: function (e) { | |
//要求用户必须点击开始游戏 才能开始玩 | |
if(this.data.clickButton == false){ | |
wx.showModal({ | |
title:'提示', | |
content:'请点击开始游戏,才能玩', | |
}) | |
return | |
} | |
//找到点击位置 | |
var ds = e.target.id | |
var i = Number(ds.substr(0, 1)) | |
var j = Number(ds.substr(1, 2)) | |
// this.data.bts[i][j].bgcolor="white" | |
// this.data.bts[i][j].text="" | |
// // this.data.bts[i][j].ftcolor="" | |
//如果点到地雷 | |
if (this.data.bts[i][j].dilei == 1) { | |
this.data.bts[i][j].bgcolor="white" | |
this.data.bts[i][j].text="*" | |
this.data.bts[i][j].ftcolor="red" | |
wx.showModal({ | |
title: '提示', | |
content: '你点到地雷了,游戏结束!'+'\n'+'所用时间为:'+this.data.timeformat, | |
}) | |
clearInterval(this.data.timer) | |
this.init() | |
}else{ //没点到地雷 | |
this.aotoClick(i,j)//开始递归当前的周围 | |
//每次点击后都检查是否胜利 | |
if(this.isVictory()==true){ | |
wx.showModal({ | |
title: '提示', | |
content: '恭喜你翻开所有地雷!', | |
}) | |
this.init() | |
} | |
} | |
this.setData({ bts: this.data.bts }) | |
}, | |
isVictory:function(){ | |
var flag = true; | |
for (var i = 0; i < this.defaultRow; i++) { | |
for (var j = 0; j < this.defaultColumn; j++) { | |
if(this.data.bts[i][j].dilei==0 && this.data.bts[i][j].bgcolor=="yellow") | |
{ | |
flag=false | |
break | |
} | |
} | |
} | |
return flag | |
} | |
}) |
index.wxss
.main{ | |
display: flex; | |
flex-direction: column; | |
border: 1px solid black; | |
} | |
.yy{ | |
display: flex; | |
flex-direction: row; | |
} | |
.xx{ | |
border: 1px solid black; | |
width: 100%; | |
height: 60px; | |
margin: 2px; | |
text-align: center; | |
line-height: 60px; | |
font-size: 35px; | |
} | |
.time{ | |
display: flex; | |
background: blueviolet; | |
padding-left: 2vw; | |
height: 7vh; | |
line-height: 7vh; | |
} | |
.using-time{ | |
width: 150px; | |
font-weight: 700; | |
} | |
.start-game{ | |
/* position: relative; */ | |
font-size: 15px; | |
padding-left: 80px; | |
font-weight: 700; | |
color: rgb(63, 204, 34); | |
} | |
.set-up{ | |
padding-left: 85vw; | |
margin-bottom: 2vh; | |
height: 20px; | |
} |
setUp目录下的代码文件
setUp.wxml (微信中所有页面代码它默认名叫 index.wxml,不用管它)
<!--index.wxml--> | |
<label class="title">你可以只设置一个数据,其他数据为系统默认数据</label> | |
<view class="firstNum"> | |
<!-- <text>请输入第一个运算数:</text> --> | |
<label class="text" >请输入方块数的行数: </label> | |
<input type="digit" bindinput="input1" style=" border: 2rpx solid #ccc; width:150px; margin-left: 5px; "/> | |
</view> | |
<view class="secondNum"> | |
<text class="text">请设置方块数的列数:</text> | |
<input type="digit" bindinput="input2" style=" border: 2rpx solid #ccc; width:150px; margin-left: 5px;"/> | |
</view> | |
<view class="dilei"> | |
<text class="text">请设置地雷数:</text> | |
<input type="digit" bindinput="input3" style=" border: 2rpx solid #ccc; width:150px; margin-left: 5px;"/> | |
</view> | |
<button bindtap="jump" class="jump">确定</button> |
setUp.js
// index.js | |
const app = getApp() | |
Page({ | |
// data: { | |
// num1: 0, | |
// num2: 0, | |
// result: 0 | |
// }, | |
input1(e) { | |
// 下面代码将本页面数据传给全局变量 | |
// var app = getApp() | |
app.globalData.row = e.detail.value | |
// this.setData({ | |
// num1: parseFloat(e.detail.value) | |
// }) | |
}, | |
input2(e) { | |
app.globalData.column = e.detail.value | |
// this.setData({ | |
// num2: parseFloat(e.detail.value) | |
// }) | |
}, | |
input3(e){ | |
app.globalData.dilei = e.detail.value | |
}, | |
jump:function(){ | |
wx.navigateTo({ | |
url: '../index' | |
}) | |
} | |
}) |
setUp.wxss
/**index.wxss**/ | |
.text{ | |
font-size: 13px; | |
font-weight: 600; | |
} | |
.firstNum, | |
.secondNum { | |
margin: 50rpx; | |
display: flex; | |
flex-direction: row; | |
height:50px; | |
} | |
.dilei{ | |
display: flex; | |
font-size: 13px; | |
font-weight: 600; | |
padding-left: 18vw; | |
} | |
.jump{ | |
background: rgb(204, 19, 221); | |
margin-top: 50px; | |
} | |
.title{ | |
font-size: 13px; | |
color:crimson; | |
padding-left: 6vw; | |
} |
由于涉及页面传递数据,所以还有一个app代码
app.js
// app.js | |
App({ | |
globalData:{ | |
row:0, | |
column:0, | |
dilei:0 | |
}, | |
onLaunch() { | |
// 展示本地存储能力 | |
const logs = wx.getStorageSync('logs') || [] | |
logs.unshift(Date.now()) | |
wx.setStorageSync('logs', logs) | |
// 登录 | |
wx.login({ | |
success: res => { | |
// 发送 res.code 到后台换取 openId, sessionKey, unionId | |
} | |
}) | |
}, | |
globalData: { | |
userInfo: null | |
} | |
}) |