实验小提醒,打开微信小程序模板时,一定要看清楚,要选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
}
})