1、微信排行榜的核心三点:开放数据域的访问方式,sharedCanvas操作、具体调用方法
1.1 主域做排行榜背景版设置,定义数据存储结构,上传数据记录,postMessage方法
数据存储结构:
let Consts = {
OpenDataKeys: {
InitKey: "initKey",
Grade: "testkey",
LevelKey: "reachlevel",
ScoreKey: "levelScore", // json.string
},
DomainAction: {
FetchFriend: "FetchFriend",
FetchGroup: "FetchGroup",
FetchFriendLevel: "FetchFriendLevel", //好友关卡进度排行
FetchFriendScore: "FetchFriendScore", //好友关卡得分排行
HorConmpar: "HorConmpar", //横向比较 horizontal comparison
Paging: "Paging",
Scrolling: "Scrolling"
},
}
上传数据:
window["wx"].setUserCloudStorage({
KVDataList: [
{ key: Consts.OpenDataKeys.ScoreKey+level, value: score },
],
success: (res) => {
console.log("uploadScore success:res=>", res);
},
fail: (res) => {
console.log("uploadScore fail:res=>", res);
}
});
//向子域发送消息
postMessage(action, data=null, dataEx=null) {
if(!window["wx"]) return;
let openDataContext = window["wx"].getOpenDataContext();
openDataContext.postMessage({
action: action,
data: data,
dataEx:dataEx,
});
}
1.2 子域借助cocos官方论坛(forum.cocos.com)大佬(魏书、caochao等)写的index.js(详细源代码参见链接http://forum.cocos.com/t/demo-api/64299)。
1.2.1 监听主域的postMessage
listen() {
//msg -> {action, data}
wx.onMessage(msg => {
//console.log("ranklist wx.onMessage", msg);
switch (msg.action) {
case Consts.DomainAction.HorConmpar:
this.clearFlag = true
this.fetchHorFriendScoreData(msg.data, msg.dataEx)
// this.horizontalComparison()
break;
case Consts.DomainAction.FetchFriendLevel:
this.clearFlag = true
this.fetchFriendLevelData();
break;
case Consts.DomainAction.FetchFriendScore:
this.clearFlag = true
this.fetchFriendScoreData(msg.data);
break;
case Consts.DomainAction.FetchGroup:
if (!msg.data) {
return;
}
this.fetchGroupData(msg.data);
break;
case Consts.DomainAction.Paging:
const page = msg.data;
this.curPageIndex += page
if (this.curPageIndex < 0) {
this.curPageIndex = 0;
console.log("已是第一页")
return;
} else if (this.curPageIndex > Max_Page) {
this.curPageIndex = Max_Page
console.log("已是最后一页")
return;
}
this.showPagedRanks(this.curPageIndex);
break;
case Consts.DomainAction.Scrolling:
this.clearFlag = false
if (!this.gameDatas.length) {
return;
}
const deltaY = msg.data;
const newOffsetY = this.offsetY + deltaY;
if (newOffsetY < 0) {
// console.log("前面没有更多了");
return;
}
if (newOffsetY + PAGE_SIZE * ITEM_HEIGHT > this.maxOffsetY) {
// console.log("后面没有更多了");
return;
}
this.offsetY = newOffsetY;
this.showRanks(newOffsetY);
break;
default:
console.log(`未知消息类型:msg.action=${msg.action}`);
break;
}
});
}
1.2.2 通过Canvas绘制排行榜内容(排名、头像、积分等)
drawRankItemEx(ctx, rank, data, itemGapY) {
const nick = data.nickname.length <= 10 ? data.nickname : data.nickname.substr(0, 9) + "...";
const kvData = data.KVDataList[0];
const grade = kvData ? kvData.value : 0;
//背景颜色
if (rank % 2 == 1) {
//ctx.fillStyle = "#c0d0d8";
//ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT);
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowColor = 'rgba(100,100,100,0.5)';
ctx.shadowBlur = 1.5;
ctx.fillStyle = 'rgba(205,220,57,0.5)';
//ctx.fillRect(0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT)
this.drawRoundRect(ctx, 0, itemGapY, ITEM_WIDTH, ITEM_HEIGHT, 30)
}
//名次 这里可以设置前几名的名次背景
if (rank <= 2) {
const rankImg = wx.createImage();
rankImg.src = `./wx-open-data-project/No${rank}.png`;
rankImg.onload = () => {
// if (prevOffsetY == this.offsetY) {
ctx.drawImage(rankImg, 10, 30 + itemGapY, 78, 82);
// }
};
ctx.fillStyle = "#ffffff";
ctx.textAlign = "right";
ctx.baseLine = "middle";
ctx.font = "60px Helvetica";
ctx.fillText(`${rank}`, 60, 90 + itemGapY);
} else {
ctx.fillStyle = "#BDBDBD";
ctx.textAlign = "right";
ctx.baseLine = "middle";
ctx.font = "60px Helvetica";
ctx.fillText(`${rank}`, 60, 80 + itemGapY);
}
//头像
const avatarX = 120;
const avatarY = 15 + itemGapY;
const avatarW = 120;
const avatarH = 120;
this.drawAvatar(ctx, data.avatarUrl, avatarX, avatarY, avatarW, avatarH, (avatarImg) => {
// if (prevOffsetY == this.offsetY) {
ctx.drawImage(avatarImg, avatarX, avatarY, avatarW, avatarH);
// }
if(this.drawIconCount>=this.gameDatas.length-1 || this.drawIconCount >=PAGE_SIZE-1){
this.drawIconCount = 0;
this.showRanks(this.curOffsetY)
}else{
this.drawIconCount++;
}
})
//名字
ctx.fillStyle = "#9a3102";
ctx.textAlign = "left";
ctx.baseLine = "middle";
ctx.font = "40px Helvetica";
ctx.fillText(nick, 300, 80 + itemGapY);
//分数
ctx.fillStyle = "#ff7100";
ctx.textAlign = "left";
ctx.baseLine = "middle";
ctx.font = "40px Helvetica";
if (this.curDataType === Consts.OpenDataKeys.LevelKey) {
ctx.fillText(`${grade}关`, 550, 80 + itemGapY);
} else if (this.curDataType === Consts.OpenDataKeys.ScoreKey) {
ctx.fillText(`${grade}分`, 550, 80 + itemGapY);
}
}