要製做排行榜,咱們須要使用一個數組totalGroup來存儲同玩好友的數據,totalGroup中同玩好友數據格式以下:canvas
1 const totalGroup = [ 2 { 3 key: 1,//用戶排名 4 name: "xiaoming",//用戶暱稱 5 url: avatarUrl,//用戶頭像地址 6 img:image,//用戶頭像,根據頭像地址生成image 7 scroes: 95//用戶得分 8 }, 9 10 { 11 key: 2, 12 name: "xiaohua", 13 url: avatarUrl, 14 img:image, 15 scroes: 90 16 }, 17 //... 18 ]
當遊戲完成時,玩家得分會上傳至用戶託管數據,totalGroup根據用戶同玩好友託管數據進行更新,排行榜根據totalGroup中的數據進行渲染。數組
遊戲各階段實現的功能總結以下:函數
1.遊戲初始化時post
根據同玩好友數據更新totalGroup;url
2.遊戲完成時spa
將玩家得分上傳至用戶託管數據code
3.玩家打開排行榜時blog
根據同玩好友數據更新totalGroup,而後根據totalGroup渲染排行榜;排序
本文不會詳解排行榜的渲染,主要分析下面兩個問題:接口
1.上傳玩家得分至用戶託管數據
2.根據同玩好友數據更新totalGroup
因爲遊戲邏輯是在主域中編寫的,因此須要在主域中把得分等數據傳入開方數據域(關於主域和開放數據域的概念請參考官方文檔,這裏不詳述),接口以下:
1 //主域中編寫 2 function setScore(score){ 3 var openDataContext = new WxgameOpenDataContext(); 4 5 var info={ 6 command:"setScore", 7 score:score, 8 timeStamp:new Date().getTime() 9 }; 10 11 openDataContext.postMessage(info); 12 }
這裏的timeStamp屬性是得分時的時間戳,爲了實現只對本週同玩好友進行排行的功能。而後在開方數據域中接受並處理信息:
1 //在開方數據域中編寫 2 wx.onMessage((data) => { 3 if (data.command == 'setScore'){ 4 setScore(data);//處理得分 5 }else if(data.command == 'preload'){ 6 //遊戲初始化時預加載資源和根據同玩好友數據更新totalGroup; 7 }else if(data.command == 'open'){ 8 //根據同玩好友數據更新totalGroup及渲染排行榜; 9 } 10 });
在setStore中先判斷分數是不是本週最高分,如果則將分數上傳至用戶託管數據:
1 //在開方數據域中編寫 2 function setScore(data){ 3 var score=data.score; 4 var timestamp=data.timeStamp; 5 6 /* 7 判斷totalGroup是否存在當前用戶,若不存在則更新分數,若存在則判 斷其中的分數是否大於score,若大於則退出,不然更新分數。 8 */ 9 for(var i=0;i<totalGroup.length;i++){ 10 var name=totalGroup[i].name; 11 var lastScore=totalGroup[i].scroes; 12 var username=userData[0].nickname;//userData中存儲用戶數據信息,在遊戲加載時初始化,代碼附在後面 13 if (username == name && lastScore >= score){ 14 return; 15 } 16 } 17 18 //更新用戶託管數據 19 return new Promise((resolve, reject) => { 20 wx.setUserCloudStorage({ 21 KVDataList: [{ 22 key: "score", 23 value: JSON.stringify(score), 24 }, { 25 key: "timestamp", 26 value: JSON.stringify(timestamp), 27 }, ], 28 29 success: function (res) { 30 resolve(); 31 }, 32 }) 33 }) 34 }
獲取用戶數據userData,遊戲初始化時執行
1 //在開方數據域中編寫 2 wx.getUserInfo({ 3 openIdList: ['selfOpenId'], 4 lang: '', 5 success: function(res) { 6 userData=res.data; 7 }, 8 })
爲了實現只對本週玩家分數進行排行的功能,totalGroup中只存儲本週玩家的數據;
1 function updateTotalGroup (){ 2 3 //按分數大小進行排序的排序函數 4 function compare(obj1, obj2) { 5 var score1 = parseInt(obj1.scroes); 6 var score2 = parseInt(obj2.scroes); 7 if (score1 > score2) { 8 return -1; 9 } else { 10 return 1; 11 } 12 } 13 14 wx.getFriendCloudStorage({ 15 keyList: ["score","timestamp"], 16 success: function (res) { 17 //先清空totolGroup 18 totalGroup.splice(0,totalGroup.length); 19 var data = res.data; 20 21 for (let i = 0; i < data.length; i++) { 22 if (data[i].KVDataList.length<2){ 23 continue; 24 } 25 //獲取得分的時間戳並判斷是不是本週,若是是則將數據存入totalGroup 26 var timestamp=data[i].KVDataList[1].value; 27 if (isCurrentWeek(timestamp)){ 28 var obj = { 29 key: i, 30 openid:data[i].openid, 31 name: data[i].nickname, 32 url: data[i].avatarUrl, 33 img: null, 34 scroes: data[i].KVDataList[0].value 35 } 36 totalGroup.push(obj); 37 } 38 } 39 //排序及設置頭像 40 totalGroup.sort(compare); 41 for (let i = 0; i < totalGroup.length; i++) { 42 const img = wx.createImage(); 43 img.src = totalGroup[i].url; 44 totalGroup[i].img = img; 45 totalGroup[i].key = i + 1; 46 } 47 //渲染排行榜 48 renderRank(totalGroup)//實現過程省略 49 50 }) 51 }
經過時間戳判斷分數是不是本週更新:
1 function isCurrentWeek(timestamp){ 2 if(timestamp==undefined){ 3 return false; 4 } 5 var date=new Date(), 6 day=date.getDay()==0?7:date.getDate(), 7 hours=date.getHours(), 8 minutes=date.getMinutes(), 9 seconds = date.getSeconds(), 10 timefromSunday=(day*24*3600+hours*3600+minutes*60+seconds)*1000,//星期日凌晨0點到此時的毫秒數 11 time=date.getTime()-timefromSunday;//1970年1月1人至上週日凌晨的毫秒數; 12 13 return parseInt(timestamp)>time//若時間戳大於週日,則時間戳標誌的事件發生在本週; 14 }
在開方數據中渲染完排行榜後,在主域中可經過下面接口獲取在開方數據域中建立的canvas;
const openDataContext = wx.getOpenDataContext();
const sharedCanvas = openDataContext.canvas;