参考:
cocos版本:2.4.4
微信开发者工具版本:1.05.2103190
demo下载地址:cocos2_4_4_wx_rank.zip
一般微信小游戏排行榜分为世界排行榜和好友排行榜,现在来实现排行榜功能。
原理
为了保护数据,微信好友数据只能在开放域使用,所以除了游戏主项目以外,需要再创建一个项目作为开放域项目。
开放域项目要显示在主域中,需要组件subContextView,这个组件就像小电视,播放开放域的界面。
当显示世界排行榜时,关闭小电视。当显示好友排行榜时,打开小电视。
一 创建主项目
创建一个普通的ts项目
主场景只放一个排行榜按钮
点击排行榜按钮,打开排行榜面板
点击世界排行榜时,隐藏subContextView;点击好友排行榜时,显示subContextView,并使用微信接口postMessage通知开放域我要显示好友排行榜。
RankPanel.ts代码如下:
const { ccclass, property } = cc._decorator; /** * 排行榜 * @author chenkai 2021.3.2 */ @ccclass export default class RankPanel extends cc.Component { @property(cc.Toggle) //世界排行榜按钮 worldToggle: cc.Toggle = null; @property(cc.Toggle) //好友排行榜按钮 friendToggle: cc.Toggle = null; @property(cc.Node) //世界排行榜 worldRank: cc.Node = null; @property(cc.Node) //好友排行榜 friendRank: cc.Node = null; @property(cc.Button) //关闭按钮 closeBtn: cc.Button = null; @property(cc.SubContextView) //开放域容器 subContextView: cc.SubContextView = null; onLoad() { //按钮事件 this.worldToggle.node.on("toggle", this.onToggleTap, this); this.friendToggle.node.on("toggle", this.onToggleTap, this); this.closeBtn.node.on(cc.Node.EventType.TOUCH_END, this.onCloseTap, this); //默认显示世界排行榜 this.showWorldRank(); } /**关闭排行榜 */ private onCloseTap() { this.node.removeFromParent(false); this.node.destroy(); } /**点击切换排行榜 */ private onToggleTap(e: cc.Toggle) { switch (e) { case this.worldToggle: this.showWorldRank(); break; case this.friendToggle: this.showFriendRank(); break; } } /**显示世界排行榜 */ private showWorldRank() { this.worldRank.active = true; this.friendRank.active = false; this.subContextView.node.active = false; } /**显示好友排行榜 */ private showFriendRank() { this.worldRank.active = false; this.friendRank.active = true; this.subContextView.node.active = true; window["wx"].getOpenDataContext().postMessage({ cmd: "ShowFriendRank", data: null }); } }
因为好友数据里是空的,所以每次进入排行榜,我们就使用setUserCloudStorage保存一个测试数据,托管数据的key值是score,获取托管数据是根据这个key值来获取的。
玩家的分数score=999,这个保存函数可以在Main.ts里或者RankPanel.ts里调用。
/**保存用户数据 */ public setUserCloudStorage() { return new Promise((resolve, reject) => { //测试数据 let value = { "wxgame": { "score": 999, "update_time": 1513080573 }, "cost_ms": 36500 } let key = "score"; let KVData = { key: key, value: JSON.stringify(value) }; let KVDataList = [KVData]; window["wx"].setUserCloudStorage({ KVDataList: KVDataList, success(res) { console.log("[WxPlatform] 保存用户数据成功:", KVDataList); resolve(true); }, fail(res) { console.log("[WxPlatform] 保存用户数据失败:", KVDataList); reject(false); } }) }); }
构建发布平台选择微信小游戏,设置开放域代码目录为wxOpenData,这个名称必须和开放域项目构建发布时的游戏名称一致。开放域游戏名称后面会讲到。
发布的项目用微信小游戏工具打开,没有appid,可以选择工具提供的测试号。
二 创建开放域项目
同样创建一个ts项目,设置场景和主项目的subContextView一样大小,例如500x500。
在开放域项目中创建好友排行榜面板
当主项目点击好友排行榜,使用微信接口postMessage向开放域发送消息,开放域用window["wx"].onMessage来接收消息
//接收主域来的消息 window["wx"].onMessage((obj)=>{ switch (obj.cmd) { case "ShowFriendRank": //显示好友排行榜 break; case "HideFriendRank": //隐藏好友排行榜 break; } });
当收到显示好友排行榜的消息时,开放域使用getFriendCloudStorage获取好友数据,KVDataList就是之前保存的托管数据,key值是socre,因为只有一条数据,所以取KVDataList[0]也可以
根据好友数据创建排行榜列表Item
window["wx"].getFriendCloudStorage({ keyList: keyList, success:(res)=>{ console.log("[openData] 获取所有好友数据成功:", res); let data = res.data; for (var i = 0; i < data.length; i++) { //解析数据 let userInfo: any = data[i]; let openid = userInfo.openid; //微信好友openid let nickname = userInfo.nickname; //微信好友昵称 let avatarUrl = userInfo.avatarUrl; //微信好友头像 let KVDataList = userInfo.KVDataList; //微信好友托管数据 let score = 0; //从托管数据中解析出分数 if (KVDataList[0] != null) { score = JSON.parse(KVDataList[0].value).wxgame.score; } //to do 创建item } }, fail(res) { //to do } });
微信的头像加载,使用远程加载loadRemote。
/**加载微信头像 */ public setSprite(icon: cc.Sprite, avatarUrl: string) { if (avatarUrl == null || avatarUrl.length == 0) { icon.spriteFrame = null } else { cc.assetManager.loadRemote(avatarUrl, { ext: '.png' }, (err, texture: any) => { icon.spriteFrame = new cc.SpriteFrame(texture); }); } }
构建发布开放域
游戏名称wxOpenData,必须和主项目的构建发布时配置的开放域代码目录一致。
发布平台选择微信小游戏开放数据域
发布路径是主项目微信小游戏的发布目录: C:\Users\lexun\Desktop\cocos2_4_4_wx_rank\client\build\wechatgame
到这里,基本完成了。每次修改主项目或者开放域项目,都必须重新构建发布一次,微信开放者工具会自动更新编译。