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


要制作排行榜,我們需要使用一個數組totalGroup來存儲同玩好友的數據,totalGroup中同玩好友數據格式如下:

 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.游戲初始化時

根據同玩好友數據更新totalGroup;

2.游戲完成時

將玩家得分上傳至用戶托管數據

3.玩家打開排行榜時

根據同玩好友數據更新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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM