Unity制作微信小游戏(1)- 好友排行榜(多榜单)

7 篇文章 0 订阅
2 篇文章 0 订阅

目录

1.初衷

2.插件

3.好友排行榜

4.注意事项

5.个人作品


1.初衷

        有了Unity转换微信小游戏的插件后,就想着做一款自己的小游戏,跑了一遍开发流程,最终也顺利上线;过程中碰到不少各种各样的坑,记录一下,也许能帮到一些想做的朋友。

        书写顺序随心所欲,本文先讲好友排行榜

2.插件

        官方插件链接

3.好友排行榜

        官方有排行榜的示例(如下图),大家有空去下载看一下,很多博客都有做详情介绍,就不多做介绍了

        这里主要讲一下多榜单怎么实现(如下图所示:记录两个不同的数据在榜中显示)

        官方插件提供的仅支持单榜,但是多榜单要怎么做呢?

        先看一下插件导入后的层次结构,如下图:

        这里open-data即为显示排行榜数据的开放数据域模块,我们需要改动以下几个地方(仅做参照):

        1)index.js:

          A.MessageType新增4个枚举

// setUserRecord(RANK_KEY, Math.ceil(Math.random() * 1000)); // 屏蔽测试数据 
const MessageType = {
    WX_RENDER: 'WXRender',
    WX_DESTROY: 'WXDestroy',
    SHOW_FRIENDS_RANK: 'showFriendsRank',
    SHOW_GROUP_FRIENDS_RANK: 'showGroupFriendsRank',
    SET_USER_RECORD: 'setUserRecord',
    // -------------------------------- < 新增4个显示枚举 > --------------------------------
    SHOW_FRIENDS_CHALLENGE_RANK: 'showFriendsChallengeRank',
    SHOW_FRIENDS_HIDE_RANK: 'showFriendsHideRank',
    SHOW_GROUP_FRIENDS_CHALLENGE_RANK: 'showGroupFriendsChallengeRank',
    SHOW_GROUP_FRIENDS_HIDE_RANK: 'showGroupFriendsHideRank',
    // -------------------------------- < 新增4个显示枚举 > --------------------------------
};

         B.main函数改为如下

function main() {
    wx.onMessage((data) => {
        console.log('[WX OpenData] onMessage', data);
        if (typeof data === 'string') {
            try {
                // eslint-disable-next-line no-param-reassign
                data = JSON.parse(data);
            }
            catch (e) {
                console.error('[WX OpenData] onMessage data is not a object');
                return;
            }
        }
        switch (data.type) {
            // 来自 WX Unity SDK 的信息
            case MessageType.WX_RENDER:
                initOpenDataCanvas(data);
                break;
            // 来自 WX Unity SDK 的信息
            case MessageType.WX_DESTROY:
                Layout.clearAll();
                break;
            // 下面为业务自定义消息
            case MessageType.SHOW_FRIENDS_RANK:
                renderFriendsRank(1);
                break;
            case MessageType.SHOW_FRIENDS_CHALLENGE_RANK:
                renderFriendsRank(2);
                break;
            case MessageType.SHOW_FRIENDS_HIDE_RANK:
                renderFriendsRank(3);
                break;
            case MessageType.SHOW_GROUP_FRIENDS_RANK:
                renderGroupFriendsRank(data.shareTicket, 1);
                break;
            case MessageType.SHOW_GROUP_FRIENDS_CHALLENGE_RANK:
                renderGroupFriendsRank(data.shareTicket, 2);
                break;
            case MessageType.SHOW_GROUP_FRIENDS_HIDE_RANK:
                renderGroupFriendsRank(data.shareTicket, 3);
                break;
            case MessageType.SET_USER_RECORD:
                let extra = {challenge:data.challenge, hide:data.hide};
                setUserRecord(RANK_KEY, data.score, extra);
                break;
            default:
                console.error(`[WX OpenData] onMessage type 「${data.type}」 is not supported`);
                break;
        }
    });
}

        2)data/index.js:

         A.getWxGameData函数改为如下

function getWxGameData(item) {
    let source;
    try {
        source = JSON.parse(item.KVDataList[0].value);
    }
    catch (e) {
        source = {
            wxgame: {
                score: 0,
                update_time: getCurrTime(),
            },
        };
    }
    // return source.wxgame;
    return source;
}

         B.以下3个函数新增参数showType及相应的改动,详见如下

function rankDataFilter(res, showType = 1, selfUserInfo = false) {
    const data = (res.data || []).filter((item) => item.KVDataList && item.KVDataList.length);
    return data
        .map((item) => {
        let data = getWxGameData(item);
        console.log('[WX OpenData] rankDataFilter() data: ', data);
        // const { score, update_time: updateTime } = data.wxgame.score;
        let score = data.wxgame.score;
        switch (showType)
        {
            case 1:
            score = data.wxgame.score;
            break;
            case 2:
            score = data.challenge;
            break;
            case 3:
            score = data.hide;
            break;
            default:
            console.error(`[WX OpenData][Error] rankDataFilter() showType: ${showType} is not case!`);
        }
        const updateTime = data.wxgame.update_time;
        console.log(`[WX OpenData] rankDataFilter() score: ${score}, showType: ${showType}`);
        item.score = score;
        item.update_time = updateTime;
        /**
         * 请注意,这里判断是否为自己并不算特别严谨的做法
         * 比较严谨的做法是从游戏域将openid传进来,示例为了简化,简单通过 avatarUrl 来判断
         */
        if (selfUserInfo && selfUserInfo.avatarUrl === item.avatarUrl) {
            item.isSelf = true;
        }
        return item;
    })
        // 升序排序
        .sort((a, b) => b.score - a.score);
}
/**
 * 获取好友排行榜列表
 * API文档可见:https://developers.weixin.qq.com/minigame/dev/api/open-api/data/wx.getFriendCloudStorage.html
 */
export function getFriendRankData(key, showType, needMarkSelf = true) {
    console.log('[WX OpenData] getFriendRankData with key: ', key);
    return getFriendCloudStorage({
        keyList: [key],
    }).then((res) => {
        console.log('[WX OpenData] getFriendRankData success: ', res);
        if (needMarkSelf) {
            getSelfPromise = getSelfPromise || getSelfData();
            return getSelfPromise.then(userInfo => rankDataFilter(res, showType, userInfo));
        }
        return rankDataFilter(res, showType);
    });
}
/**
 * 获取群同玩成员的游戏数据。小游戏通过群分享卡片打开的情况下才可以调用。该接口需要用户授权,且只在开放数据域下可用。
 * API文档可见: https://developers.weixin.qq.com/minigame/dev/api/open-api/data/wx.getGroupCloudStorage.html
 */
export function getGroupFriendsRankData(shareTicket, key, showType, needMarkSelf = true) {
    console.log('[WX OpenData] getGroupFriendsRankData with shareTicket and key: ', shareTicket, key);
    return getGroupCloudStorage({
        shareTicket,
        keyList: [key],
    }).then((res) => {
        console.log('[WX OpenData] getGroupFriendsRankData success: ', res);
        if (needMarkSelf) {
            getSelfPromise = getSelfPromise || getSelfData();
            return getSelfPromise.then(userInfo => rankDataFilter(res, showType, userInfo));
        }
        return rankDataFilter(res, showType);
    });
}

        3)render/styles/friendRank.js:用来设置图片的显示位置、长宽、圆角等;这里可以参照原有改动

        4)render/tpls/friendRank.js:用来设置显示的xml,配合上面一条

export default function anonymous(it, showType) {
    let out = '<view class="container" id="main"> <view class="rankList"> <scrollview class="list" scrollY="true"> ';
    const arr1 = it.data;
    if (arr1) {
        let item;
        let index = -1;
        const l1 = arr1.length - 1;
        while (index < l1) {
            item = arr1[(index += 1)];
            let rankIndex = index + 1;
            // let name = item.nickname + item.nickname + item.nickname;
            let name = item.nickname;
            let itemIconIndex = showType;
            out += ` <view class="listItem"> <image src="open-data/render/image/rankBg.png" class="rankBg"></image> <text class="rankIndex" value="${rankIndex}"></text>`;
            if (rankIndex <= 3)
              out += `<image class="rankMark" src="open-data/render/image/ui_rank${rankIndex}.png"></image>`;
            out += ` <image class="rankAvatarBg" src="open-data/render/image/rankAvatar.png"></image> <image class="rankAvatar" src="${item.avatarUrl}"></image> <text class="rankName" value="${name}"></text>  <text class="rankScoreVal" value="${(item.score || 0) + (itemIconIndex > 1 ? ' 关' : '')}"></text>`;
            if (itemIconIndex == 1)
              out += `<image class="rankItemIcon1" src="open-data/render/image/ui_item1.png"></image>`;
            // else if (itemIconIndex == 2)
            //   out += `<image class="rankItemIcon2" src="open-data/render/image/ui_item2.png"></image>`;
            out += `</view>`;
        }
    }
    out += ' </scrollview> </view></view>';
    return out;
}

        5)render/image:排行榜的显示图片,配合以上两条

        6)Unity端调用:

    [System.Serializable]
    public class OpenDataMessage
    {
        public string type;
        public string shareTicket;
        public int score;
        public int challenge;
        public int hide;
    }
    
    public void SetFriendRankData(int score, int challenge, int hide)
    {
        OpenDataMessage msgData = new OpenDataMessage();
        msgData.type = "setUserRecord";
        msgData.score = score;
        msgData.challenge = challenge;
        msgData.hide = hide;
        string msg = LitJson.JsonMapper.ToJson(msgData);
        WX.GetOpenDataContext().PostMessage(msg);
    }

4.注意事项

        1)可以在Unity转换为小游戏后,在微信开发者工具里直接改open-data里的内容,便于运行查看;调整完成后,记得把open-data文件夹替换Unity里WX-WASM-SDK-V2文件夹下的同名目录

        2)要显示开放数据域的内容,需要用到小程序插件:开放数据域渲染库,记得添加

        3)game.json中添加如下插件

"Layout"      : {
      "version" : "1.0.7",
      "provider" : "wx7a727ff7d940bb3f",
      "contexts" : [
        {
          "type" : "openDataContext"
        }
      ]
    }

        4)每次更新小程序转换插件时,一般来说open-data不用导入(不然还得自己比对,把改动的内容找回来)

5.个人作品

        小游戏:小小狼吃羊 

        感兴趣的可以玩玩看^_^

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值