微信小程式-實戰鞏固(二)
剛剛寫了小程式入門沒幾天,小程式就開放個人開發者資格,感覺為我而來啊 (≧▽≦)/。迫不及待的去註冊,準備將之前的處女作傳上去體驗一把,結果卡在了伺服器配置上:免費的果然不靠譜/(ㄒoㄒ)/~~,後來嘗試用個人伺服器轉發代理請求,發現不支援http,必須https!必須https!必須https!
好不容易做的專案不能上線,感覺心被掏空了,這種憋屈大家懂得~,於是不甘寂寞的我,準備做個不需要請求的單機版,就是這麼機智(*^__^*) 嘻嘻……文末高能,慎入~
接下來我們開始動手吧,之前做過類似連連看,這次準備嘗試做個小程式掃雷,來個最終效果圖,先睹為快吧
因為有了上一節入門基礎,這一節就講的快一點,如果有什麼不太理解的,可以去看我的上一篇文章
一、初始化專案
主要包括:設定app.js、app.json和app.wxss三個檔案,建立pages檔案結構
//app.js,將遊戲配置檔案放在APP中,可實現跨頁之間共享
App({
row:12,//掃雷遊戲的行數
column:8,//掃雷遊戲的列數
bomb:8//包含雷的總數
})
二、遊戲頁面邏輯
重點在首頁遊戲邏輯的處理,因為小程式以資料為驅動,無法操作dom,所以很多實現最終要落實到資料上,檢視如下index.js
//index.js Page({ data: { dialog_warn:false,//通過修改此資料值,改變彈框的顯示狀態 dialog_suc:false, //遊戲成功,設為true,檢視層通過wx:if來判斷是否渲染該彈窗 count:null,//翻牌計數,初始值為app.row*app.column gamearr:[]//遊戲地圖的基礎資料(二維陣列),根據此來生成遊戲 } })
<!--index.wxml--> <view class="dialog warn" wx:if="{{dialog_warn}}"> <icon type="warn" size="60" color="orange"></icon> <text>Game Over</text> <button bindtap="reset">重新開始</button> </view> <view class="dialog success" wx:if="{{dialog_suc}}"> <icon type="success" size="60" color="green"></icon> <text>Success~</text> <button bindtap="reset">重新開始</button> </view>
根據app.js中的資料,生成遊戲地圖資料:gamearr
setgamearr:function(row,column,bomb){//根據行列設定遊戲二維陣列(地圖)
var that=this;
var arrmap=[];//二維初始陣列,全為空
for(var i=row-1;i>=0;i--){
arrmap[i]=[];
for(var j=column-1;j>=0;j--){arrmap[i][j]={val:"",cover:true};}//val用來記錄周邊雷的數量,cover用來記錄是否翻開:無dom操作只能用資料記錄狀態
}
var arr=[];//一維自然數
for(var k=row*column-1;k>=0;k--){arr[k]=k}
//隨機炸彈位置
for(var h=bomb-1;h>=0;h--){
var seat=arr.splice(Math.floor(Math.random()*arr.length),1)[0]
var r=Math.floor(seat/column),c=Math.floor(seat%column);
//console.log(seat+'n'+r+","+c);
arrmap[r][c].val="B";
arrmap=that.addcount(r,c,arrmap)//給炸彈周圍九宮格增加標記數
}
that.setData({gamearr:arrmap})
},
給炸彈周圍九宮格增加標記數
addcount:function(r,c,arrmap){
var that=this;
if(r-1>=0){//九宮格上三個
if(c-1>=0 && arrmap[r-1][c-1].val!="B"){arrmap[r-1][c-1].val++}
if(arrmap[r-1][c].val!="B"){arrmap[r-1][c].val++}
if(c+1<app.column && arrmap[r-1][c+1].val!="B"){arrmap[r-1][c+1].val++}
}
if(r+1<app.row){//九宮格下三個
if(c-1>=0 && arrmap[r+1][c-1].val!="B"){arrmap[r+1][c-1].val++}
if(arrmap[r+1][c].val!="B"){arrmap[r+1][c].val++}
if(c+1<app.column && arrmap[r+1][c+1].val!="B"){arrmap[r+1][c+1].val++}
}
//九宮格左右兩個
if(c-1>=0 && arrmap[r][c-1].val!="B"){arrmap[r][c-1].val++}
if(c+1<app.column && arrmap[r][c+1].val!="B"){arrmap[r][c+1].val++}
return arrmap;
}
生成資料後,根據資料生成頁面檢視
<view class="game">
<view class="tr" wx:for="{{gamearr}}" wx:for-index="row" wx:for-item="itemrow"><!--根據資料遍歷行-->
<view class="td" wx:for="{{itemrow}}" wx:for-index="column" wx:for-item="itemcolumn" data-row="{{row}}" data-column="{{column}}" bindtap="taphandler">
<view class="mask" wx:if="{{itemcolumn.cover}}"></view><!--遮罩層,無法用偽元素before來更改狀態,只能資料來判斷了-->
<text wx:if="{{itemcolumn.val==''}}">{{itemcolumn.val}}</text><!--根據數值顯示不同樣式,如果是web能用jquery選擇器就簡單多了,這裡略顯複雜-->
<text class="color1" wx:elif="{{itemcolumn.val==1}}">{{itemcolumn.val}}</text>
<text class="color2" wx:elif="{{itemcolumn.val==2}}">{{itemcolumn.val}}</text>
<text class="color3" wx:else>{{itemcolumn.val}}</text>
</view>
</view>
</view>
遊戲控制部分,單元格tap事件
//遊戲控制部分
taphandler:function(e){
var that=this;
var r=e.currentTarget.dataset.row,c=e.currentTarget.dataset.column;//無法想jquery獲得index,只能用資料記錄,直接獲取嘍
if(that.data.gamearr[r][c].val!="B"){//如果沒點到炸彈
that.data.gamearr[r][c].cover=false;
that.data.count--;
that.setData({count:that.data.count})
if(that.data.count==app.bomb){that.setData({dialog_suc:true})}//當剩餘單元格計數等於雷數,遊戲勝利
if(that.data.gamearr[r][c].val==""){//如果點到的是空,將它周圍的四個開啟
that.data.gamearr=that.show4(r,c,that.data.gamearr)
// that.data.gamearr=that.show9(r,c,that.data.gamearr)//原先考慮九點,結果遞迴直接棧溢位了,(⊙﹏⊙)b
}
console.log(that.data.count)
}else{that.setData({dialog_warn:true})}//點到了雷,遊戲結束
that.setData({gamearr:that.data.gamearr})
}
如果點選為空,將它周圍四個翻牌,並進行遞迴操作
show4:function(r,c,arrmap){//顯示周邊的4點
var that=this;
if(r-1>=0 && arrmap[r-1][c].val==""){//上
if(arrmap[r-1][c].cover){
arrmap[r-1][c].cover=false;that.data.count--;that.setData({count:that.data.count})
that.show4(r-1,c,arrmap)//遞迴
}
}
if(r+1<app.row && arrmap[r+1][c].val==""){//下
if(arrmap[r+1][c].cover){
arrmap[r+1][c].cover=false;that.data.count--;that.setData({count:that.data.count})
that.show4(r+1,c,arrmap)//遞迴
}
}
if(c-1>=0 && arrmap[r][c-1].val==""){//左
if(arrmap[r][c-1].cover){
arrmap[r][c-1].cover=false;that.data.count--;that.setData({count:that.data.count})
that.show4(r,c-1,arrmap)//遞迴
}}
if(c+1<app.column && arrmap[r][c+1].val==""){//右
if(arrmap[r][c+1].cover){
arrmap[r][c+1].cover=false;that.data.count--;that.setData({count:that.data.count})
that.show4(r,c+1,arrmap)//遞迴
}}
return arrmap;
}
三、遊戲設定
遊戲設定就相對簡單了,直接讀取app.js的資料為設定頁的資料,操作修改則修改app資料,然後切換回遊戲頁面onshow獲取更新後的資料重新生成遊戲
// pages/set/set.js
var app = getApp();
Page({
data:{
row:app.row,
column:app.column,
bomb:app.bomb
},//遊戲設定部分,修改設定將重新生成遊戲
rowChange:function(e){app.row=e.detail.value;},
columnChange:function(e){app.column=e.detail.value;},
bombChange:function(e){app.bomb=e.detail.value;}
})
四、總結
做完了釋出上傳的時候才發現,小程式的分類裡面沒有遊戲,更多的是工具應用類,不知道小程式以後會不會放開服務類目,拭目以待吧~
專案原始檔:https://github.com/gavin125/wx_game
上傳小程式稽核等了一天,結果不通過詳情如下,(⊙o⊙)…我想一個人靜靜…