參考:http://www.pianshen.com/article/876094934/
好友排行榜微信只讓我們在開放數據域(後文都簡稱爲”子域”)裏面操作(畢竟這是人家最重要最值錢的數據了,不會讓我們拿來隨便用的),小遊戲做好後,想加入排行榜和超越好友等功能,白鷺官方也給出了詳細的教程了。目前官網的demo排行榜是分頁的,點擊查看下一頁數據,不能像scrollView那樣滾動展示數據,不是我想要的,我看了下其他人做的,說可以用一個項目做遊戲,一個項目專門放排行榜,放排行榜的項目直接導出到遊戲項目的openDataContext文件夾下。我也試着操作了下,發現坑有點難踩,遇到了個wx.getFileSystemManager not function的錯誤,後面發現在5.2.2中,使用assetsmananger而不是res,解決方案。而且這樣會多引入一次egret和game庫,其實好像也就多幾百KB而已。第一種方案;這裏我着重說一下另外一個方案,就是目前官方demo那種,在js裏面直接用canvas做出類似於scrollView那種滾動效果,其實就是監聽下Y軸滑動距離,根據滑動距離來處理canvas的位置。
想要排行榜有數據,就先上傳用戶數據到微信後臺,就是託管數據。我是在比賽結束的時候發送一個消息給子域,此消息帶上用戶分數。
platform["openDataContext"].postMessage({
command: 'updateMaxScore',
myScore: _myScore
});
然後在子域的index.js裏面監聽並處理這個消息
else if (data.command == 'updateMaxScore') {
if (myCurrentScore <= data.myScore) {
setUserCloudStorage(data.myScore);
}
getFriendCloudInfo();
}
這個setUserCloudStorage加了個上傳時間的操作,用於之後通過時間來處理週一數據清零的操作,後面會貼上完整代碼。上傳新分數後再通過getFriendCloudInfo拿新數據並過濾排序。在排行榜界面先創建一個離屏canvas
let bitmap_rank = platform["openDataContext"].createDisplayObject(null,this.stageW, rank_item_bg_Group.height, 0);
bitmap_rank.y = 80;
rank_item_bg_Group.addChild(bitmap_rank);
rank_item_bg_Group就是圖中綠色框部分,在這個上面添加canvas,方便位置調整。然後傳消息給後臺根據是否有shareTicket來顯示是好友排行榜還是羣排行榜。
let delayTime = 0;
if(game.myShareTicket != undefined && game.myShareTicket != ""){
delayTime = 1000;
}
setTimeout((e)=> {
platform["openDataContext"].postMessage({
command: "open",
shareTicket: game.myShareTicket
});
}, delayTime);
createScene創建的是除圖上紅色框之外的排行榜內容,createMyScene創建的是我的內容,就是紅色框那塊,其實可以合併到一起的,後期再整理一下。微信頭像和圖片一樣做一下預加載,先拿到頭像數據保存起來,再預加載。
function preloadAvatarUrl() {
let preloaded = 0;
let count = 0;
for (let asset in avatarUrlList) {
count++;
const img = wx.createImage();
img.onload = () => {
preloaded++;
if (preloaded == count) {
// console.log("頭像加載完成");
hasLoadRes = true;
}
}
// console.log("src:" + avatarUrlList[asset] + " asset:" + asset);
img.src = avatarUrlList[asset];
assetsAvatarUrl[asset] = img;
}
}
這個是給排行榜排序,根據用戶分數做降序處理
//給排行榜排序(降序)
var compare = function (prop) {
return function (obj1, obj2) {
var val1 = obj1[prop];
var val2 = obj2[prop];
var int1 = val1[0]["value"];
var int2 = val2[0]["value"];
if (!isNaN(Number(int1)) && !isNaN(Number(int2))) {
int1 = Number(int1);
int2 = Number(int2);
}
if (int1 < int2) {
return 1;
} else if (int1 > int2) {
return -1;
} else {
return 0;
}
}
}
這個是根據上傳分數時帶的時間戳判斷分數是否是同一周,大致思路是首先新的天數要大於老的天數,週日的天數通過getDay()獲取到時是0,轉爲7,方便處理,然後天數不同通過時間戳差值判斷是否在一週內,如果天數相同則判斷差值是否在一天內,防止這週一早上10點和下週一早上9點被判斷成一週。
//判斷是否是同一周
function isSameWeek(oldTime) {
oldTime = parseInt(oldTime);
var newTime = new Date().getTime();
let oneDayTime = 60 * 60 * 24 * 1000;
// console.log("now:" + newTime + " old:" + oldTime + " off:" + (newTime - oldTime) + " one:" + (oneDayTime * 7))
let oldDate = new Date(oldTime);
let newDate = new Date(newTime);
let oldDay = oldDate.getDay();
let newDay = newDate.getDay();
if (newDay == 0) {
newDay = 7;
}
if (oldDay == 0) {
oldDay = 7;
}
let isSame = false;
if (oldDay < newDay) {
if ((newTime - oldTime) < oneDayTime * 7) { // 時間相差小於7
isSame = true;
}
} else if (oldDay == newDay) {
if ((newTime - oldTime) < oneDayTime) {
isSame = true;
}
}
return isSame;
}
platform.js裏面也改造了下
createDisplayObject(type, width, height,offsetY) {
sharedCanvas.width = width;
sharedCanvas.height = height;
const bitmapdata = new egret.BitmapData(sharedCanvas);
bitmapdata.$deleteSource = false;
const texture = new egret.Texture();
texture._setBitmapData(bitmapdata);
const bitmap = new egret.Bitmap(texture);
bitmap.width = width;
bitmap.height = height;
bitmap.y = offsetY;
if (egret.Capabilities.renderMode == "webgl") {
const renderContext = egret.wxgame.WebGLRenderContext.getInstance();
const context = renderContext.context;
////需要用到最新的微信版本
////調用其接口WebGLRenderingContext.wxBindCanvasTexture(number texture, Canvas canvas)
////如果沒有該接口,會進行如下處理,保證畫面渲染正確,但會佔用內存。
if (!context.wxBindCanvasTexture) {
egret.startTick((timeStarmp) => {
egret.WebGLUtils.deleteWebGLTexture(bitmapdata.webGLTexture);
bitmapdata.webGLTexture = null;
return false;
}, this);
}
}
return bitmap;
}
排行榜好友我是隻顯示7個,根據Y軸滑動距離來判斷顯示哪7個數據就行,具體方法看後面代碼,寫的太多了,大家不一定有耐心看了,好久沒寫博客,有點亂,好像拆開寫比較合適啊。
下面是index.js詳細代碼,貼了全部代碼,發現顯示不了那麼多。就當附件傳上來吧,附件找不到在哪裏傳,就先直接上傳到資源裏吧index.js順便貼幾張子域效果圖。
子域的數據可以傳給主域了,一個qq羣裏同學說的,驗證了下,的確可以,現分享給大家。
在子域裏獲取到排行榜數據後,userDataList保存數據然後如下寫法:
let openContext = wx.getSharedCanvas().getContext("2d");
openContext["canvas"]["userDataList"] = JSON.stringify(userDataList);
在主域裏通過如下寫法可以拿到子域保存的排行榜數據,這些就可以在主域直接用ScrollView了,哎,發現的有點晚了啊。
let openContext = wx.getOpenDataContext();
let friendDataList:any;
if(openContext["canvas"]["userDataList"]){
friendDataList = JSON.parse(openContext["canvas"]["userDataList"]);
}
console.log("openContext");
console.log(openContext);
console.log("friendDataList");
console.log(friendDataList);