微信小程序扫雷游戏
枫渝浪天下 人气:0实验小提醒,打开微信小程序模板时,一定要看清楚,要选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 } })
加载全部内容