前言
对于一个微信小游戏来说,好友排行榜绝对是必不可少的功能,能一定程度上增加玩家的战斗力和活跃度,实实在在地增加小游戏的曝光量。
这篇文章皮皮将讲解 如何给小游戏项目加入微信好友排行榜功能 ~
不吹不黑,这绝对是新手开发者的福音!不接受任何反驳!
前排提示:文章中的 排行榜子域项目 已经上传至我的开源主页,甚至 改都不用改,接上项目就能用 ,链接在底部传送门~
微信开放数据域
要让小游戏接入微信好友排行榜功能,我们必须先了解下什么是
开放数据域
,来看看 Cocos 官方文档中的解释:
也就是说,我们的小游戏项目想要加入好友排行榜功能,就需要 单独再创建一个子项目专门用来展示好友排行榜 ,并且 只有在子项目中才可以调用微信提供的数据操作 API 。
主域(主项目)
首先我们需要在主项目中 增加一个显示排行榜的按钮 并 搭建排行榜的 UI 框架 。
我们应该尽可能将 UI 部分放在主域中展示。
必要的细节部分才在子域(子项目)中展示,保证效果的前提下越少越好啦。
public
set
(ranking: number, user: UserGameData) {
this
.rankingLabel.string = ranking.toString();
this
.nicknameLabel.string = user.nickname;
this
.scoreLabel.string = user.KVDataList[
0
].value.toString();
this
.updateAvatar(user.avatarUrl);
* 更新头像
*
@param
url 头像链接
private updateAvatar(url: string) {
let
image = wx.createImage();
image.onload =
()
=>
{
let
texture =
new
cc.Texture2D();
texture.initWithElement(image);
texture.handleLoadedTexture();
this
.avatarSprite.spriteFrame =
new
cc.SpriteFrame(texture);
image.src = url;
import RankItem from "./RankItem";
const { ccclass, property } = cc._decorator;
@ccclass
export default class Rank extends cc.Component {
@property(cc.Node)
private content: cc.Node = null;
@property(cc.Prefab)
private itemPrefab: cc.Prefab = null;
@property(cc.Node)
private loading: cc.Node = null;
protected onLoad() {
if (cc.sys.platform !== cc.sys.WECHAT_GAME_SUB) return;
// 监听来自主域的消息
wx.onMessage((msg: any) => this.onMessage(msg));
* 消息回调
* @param msg 消息
private onMessage(msg: any) {
switch (msg.event) {
case 'setScore':
this.setScore(msg.score);
break;
case 'getRank':
this.getRank();
break;
* 获取玩家分数
private getScore(): Promise<number> {
return new Promise(resolve => {
console.log('[getScore]');
wx.getUserCloudStorage({
keyList: ['score'],
success: (res: UserGameData) => {
console.log('[getScore]', 'success', res);
resolve(res.KVDataList[0] ? parseInt(res.KVDataList[0].value) : 0);
fail: () => {
console.log('[getScore]', 'fail');
resolve(-1);
* 设置玩家分数
* @param value 分数
private async setScore(value: number) {
console.log('[setScore]', value);
let oldScore = await this.getScore();
if (oldScore === -1) return;
if (value > oldScore) {
wx.setUserCloudStorage({
KVDataList: [{
key: 'score',
value: value.toString()
success: () => {
console.log('[setScore]', 'success');
fail: () => {
console.log('[setScore]', 'fail');
* 获取排行榜
private async getRank() {
console.log('[getRank]');
// 显示加载动画
this.showLoading();
// 调用微信的函数
await new Promise(resolve => {
wx.getFriendCloudStorage({
keyList: ['score'],
success: (res: any) => {
console.log('[getRank]', 'success', res);
// 对数据进行排序
res.data.sort((a: UserGameData, b: UserGameData) => {
if (a.KVDataList.length === 0 && b.KVDataList.length === 0) return 0;
if (a.KVDataList.length === 0) return 1;
if (b.KVDataList.length === 0) return -1;
return parseInt(b.KVDataList[0].value) - parseInt(a.KVDataList[0].value);
// 排序之后进行展示
this.updateRankList(res.data);
resolve();
fail: (res: any) => {
console.log('[getRank]', 'fail');
resolve();
// 关闭加载动画
this.hideLoading();
* 更新好友排行
* @param data 数据
private updateRankList(data: UserGameData[]) {
let count = Math.max(data.length, this.content.childrenCount);
for (let i = 0; i < count; i++) {
if (data[i] && this.content.children[i]) {
// 已存在节点,更新并展示
this.content.children[i].active = true;
this.content.children[i].getComponent(RankItem).set(i + 1, data[i]);
} else if (data[i] && !this.content.children[i]) {
// 节点不足,再实例化一个,更新信息
let node = cc.instantiate(this.itemPrefab);
node.setParent(this.content);
node.getComponent(RankItem).set(i + 1, data[i]);
} else {
// 节点多了,关掉吧
this.content.children[i].active = false;
* 显示加载动画
private showLoading() {
this.loading.active = true;
* 关闭加载动画
private hideLoading() {
this.loading.active = false;
点击编辑器左上方工具栏的 [ 项目 --> 项目设置 --> 模块设置 ] , 取消勾选我们子域中没有用到的组件并保存 ,这一步的目的是 减少子域的包体大小 。
首先是我们的 主域 (主项目):打开 构建发布 面板,设置好参数后填写你的微信小游戏 appid ,然后将下方的 开放数据域目录设置为你的子域项目名 ,然后进行构建。
然后是 子域 (子项目):同样是打开 构建发布 面板,将 发布平台 设置为 微信小游戏开放数据域 , 发布路径 设置为 **我们主项目的导出目录(一般为 ${ 你的项目目录/build/wechatgame/ }) **,然后进行构建。
最后,主项目和子项目都构建完成后,我们用 微信开发者工具运行我们的主项目 ,点击加载排行榜,可以看到我们已经成功加载了好友排行榜啦!
如果你那里没有显示任何东西的话,那说明你还没有上传过分数~
另外如果微信开发者工具报错“[GameOpenDataContext] 子域只支持使用 2D 渲染模式”,不用担心,这是正常情况,你的代码没问题,不必理会。
* 提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。
export function authorize(object: object): void;
* 获取用户信息。
export function getUserInfo(object: object): void;
* 向开放数据域发送消息。
export function postMessage(object: object): void;
* 监听主域发送的消息。
export function onMessage(callback: Function): void;
* 对用户托管数据进行写数据操作。允许同时写多组 KV 数据。
export function setUserCloudStorage(object: object): void;
* 获取当前用户托管数据当中对应 key 的数据。该接口只可在开放数据域下使用。
export function getUserCloudStorage(object: object): void;
* 删除用户托管数据当中对应 key 的数据。
export function removeUserCloudStorage(object: object): void;
* 监听成功修改好友的互动型托管数据事件,该接口在游戏主域使用。
export function onInteractiveStorageModified(callback: Function): void;
* 修改好友的互动型托管数据,该接口只可在开放数据域下使用。
export function modifyFriendInteractiveStorage(object: object): void;
* 获取当前用户互动型托管数据对应 key 的数据。
export function getUserInteractiveStorage(object: object): void;
* 获取可能对游戏感兴趣的未注册的好友名单。每次调用最多可获得 5 个好友,此接口只能在开放数据域中使用。
export function getPotentialFriendList(object: object): void;
* 获取群信息。小游戏通过群分享卡片打开的情况下才可以调用。该接口只可在开放数据域下使用。
export function getGroupInfo(object: object): void;
* 获取群同玩成员的游戏数据。小游戏通过群分享卡片打开的情况下才可以调用。该接口只可在开放数据域下使用。
export function getGroupCloudStorage(object: object): void;
* 拉取当前用户所有同玩好友的托管数据。该接口只可在开放数据域下使用。
export function getFriendCloudStorage(object: object): void;
* 给指定的好友分享游戏信息,该接口只可在开放数据域下使用。接收者打开之后,可以用 wx.modifyFriendInteractiveStorage 传入参数 quiet=true 发起一次无需弹框确认的好友互动。
export function shareMessageToFriend(object: object): void;
* 获取主域和开放数据域共享的 sharedCanvas。只有开放数据域能调用。
export function getSharedCanvas(): any;
* 获取开放数据域。
export function getOpenDataContext(): any;
* 创建一个图片对象。
export function createImage(): any;
* 托管数据
declare type UserGameData = {
avatarUrl: string;
nickname: string;
openid: string;
KVDataList: KVData[];
* 托管的 KV 数据
declare type KVData = {
key: string;
value: string;
* 用户信息
declare type FriendInfo = {
avatarUrl: string;
nickname: string;
openid: string;
以上皆为陈皮皮的个人观点,小生不才,文采不佳,如果写得不好还请各位多多包涵。如果有哪些地方说的不对,还请各位指出,希望与大家共同进步。
接下来我会持续分享自己所学的知识与见解,欢迎各位关注本公众号。
我们,下次见!
文弱书生陈皮皮
Input and output.