微信小遊戲排行榜設計技術梳理

要製做排行榜,咱們須要使用一個數組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、上傳玩家得分至用戶託管數據

因爲遊戲邏輯是在主域中編寫的,因此須要在主域中把得分等數據傳入開方數據域(關於主域和開放數據域的概念請參考官方文檔,這裏不詳述),接口以下:

 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 })

2、根據同玩好友數據更新totalGroup

爲了實現只對本週玩家分數進行排行的功能,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 }

3、顯示排行榜

在開方數據中渲染完排行榜後,在主域中可經過下面接口獲取在開方數據域中建立的canvas;

const openDataContext = wx.getOpenDataContext();
const sharedCanvas = openDataContext.canvas;
相關文章
相關標籤/搜索