猫有猫的方向 2024-06-06 00:08 采纳率: 88.2%
浏览 10
已结题

cocos主域调用数据库跟子域渲染问题

学习微信小游戏排行榜,微信开发者工具渲染报错!子域不能渲染的问题

img

//ShowRanks.js主域代码
cc.Class({
    extends: cc.Component,

    properties: {
        wxSubContextView: cc.Node       //主域视窗容器
    },

    onLoad() {
        },

    onClick() {
        // 调用云函数获取用户数据
        wx.cloud.callFunction({
            //查询数据库的云函数
            name: 'cloud2',
            data: {
                method: 'getGuessData' // 指定查询数据库的参数是 'getGuessData'
            },
            success: res => {
                // 获取到用户数据后,将其传递给子域
                let rankData = res.result; // 假设云函数返回的用户数据为数组形式
                this.initSubDomain(); // 初始化子域
                this.sendRankDataToSubDomain(rankData); // 向子域发送排行榜数据
            },
            fail: err => {
                console.error('云函数调用失败', err);
            }
        });
    },

    initSubDomain() {
        if (typeof wx === 'undefined') {
            return;
        }

        // 获取开放数据域
        let openDataContext = wx.getOpenDataContext();
        // 在主域中显示开放数据域
        openDataContext.postMessage({
            action: 'init',
        });
    },

    sendRankDataToSubDomain(rankData) {
        if (typeof wx === 'undefined') {
            return;
        }

        // 向开放数据域发送排行榜数据
        let openDataContext = wx.getOpenDataContext();
        openDataContext.postMessage({
            action: 'updateRanks',
            data: rankData,
        });
    },

    showRanks() {
        if (typeof wx === 'undefined') {
            return;
        }

        // 切换排行榜显示状态
        this.wxSubContextView.active = !this.wxSubContextView.active;

        // 通知子域显示或隐藏排行榜
        let openDataContext = wx.getOpenDataContext();
        openDataContext.postMessage({
            action: this.wxSubContextView.active ? 'showRanks' : 'hideRanks',
        });
    },

});

//子域OpenData.js开放数据域
cc.Class({
    extends: cc.Component,
    properties: {
        itemPrefab: cc.Prefab,      // item预制
        content: cc.Node,           // content节点
        allInfoList: [],            // 存储所有玩家信息的数组
    },
    onLoad () {
        if (typeof wx === 'undefined') {
            return;
        }
        wx.onMessage(data => {
            if (data.message) {
                if (data.message === 'updateRanks') {
                    // 获取排行榜数据并绘制
                    this.getRankDataAndDraw(data.rankData); // 接收主域传来的rankData
                } else if (data.message === 'clear') {
                    // 关闭排行榜时清空节点
                    this.content.removeAllChildren();
                }
            }
        });
    },
    getRankDataAndDraw(rankData) {
        // 清空content节点
        this.content.removeAllChildren();

        // 根据排行榜数据绘制排名列表
        for (let i = 0; i < rankData.length; i++) {
            let data = rankData[i];
            this.createItem(data.rank, data.nickName, data.avatarUrl, data.level);
        }
    },
    makeRanks() {
        // 首先将allInfoList内部元素进行排序,根据分数来降序排列
        this.allInfoList.sort((a, b) => {
            return b['level'] - a['level'];
        });
        // 清空content节点
        this.content.removeAllChildren();
        // 根据各个玩家的分数制作排名
        for (let i = 0; i < this.allInfoList.length; i++) {
            let nickName = this.allInfoList[i]['nickName'];
            let avatarUrl = this.allInfoList[i]['avatarUrl'];
            let level = this.allInfoList[i]['level'];
            this.createItem(i + 1, nickName, avatarUrl, level);
        }
    },
    createItem(rank, nickName, avatarUrl, level) {
        // 生成item
        let item = cc.instantiate(this.itemPrefab);

        // 排名
        item.children[0].getComponent(cc.Label).string = String(rank);
        // 微信名
        item.children[4].getComponent(cc.Label).string = nickName;
        // 分数
        item.children[5].getComponent(cc.Label).string = level;
        // 头像
        cc.loader.load({ url: avatarUrl, type: 'png' }, (err, texture) => {
            if (err) console.error(err);
            item.children[1].getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(texture);
        });

        // 添加到content中
        this.content.addChild(item);
    }
});

  • 写回答

13条回答 默认 最新

  • 阿齐Archie 嵌入式领域优质创作者 2024-06-06 08:32
    关注

    以下参考免费微信小程序:皆我百晓生 作答,并由阿齐Archie整理回复,若还有疑问可评论或留言。

    从您提供的错误信息和代码来看,您在微信小游戏的排行榜实现中遇到了两个主要问题:

    1. 子域渲染问题:错误提示“【GameOpenDataContext】子域只支持使用 2D 渲染模式”表明子域在渲染过程中存在兼容性问题。
    2. Canvas只读问题:错误提示“[GameOpenDataContext] Cannot assign to read only canvas”表明在子域中尝试修改canvas时遇到了权限问题。

    以下是针对这两个问题的解决方案:

    解决方案 1:解决子域渲染问题

    微信小游戏的子域确实只支持2D渲染模式。为了解决这个问题,您需要确保子域中的所有渲染操作都符合这个限制。检查子域中的代码,确保没有使用任何3D渲染相关的API。如果使用了,需要替换为2D渲染的等效操作。

    解决方案 2:解决Canvas只读问题

    这个问题通常是因为子域尝试修改主域的canvas。在微信小游戏中,子域是不允许直接修改主域的canvas的。解决这个问题的方法是使用postMessage机制来传递数据。

    • 主域:在主域中,您已经通过postMessage向子域发送了数据。确保所有需要在子域中渲染的数据都通过这种方式传递。
    • 子域:在子域中,您需要接收主域传递的数据,并根据这些数据进行渲染。不要尝试直接修改主域的canvas。

    代码调整建议

    1. 确保子域中的所有渲染操作都是基于2D的。
    2. 检查OpenData.js中是否有尝试直接操作canvas的代码,如果有,需要删除或修改。
    3. 如果需要在子域中使用canvas,可以考虑在子域内部创建一个新的canvas元素,然后在该元素上进行渲染。

    示例代码

    OpenData.js中,如果需要使用canvas进行渲染,可以创建一个新的canvas并使用2D上下文进行绘制:

    cc.Class({
        // ...
        onLoad() {
            // ...
            this.canvas = new cc.Canvas();
            this.context = this.canvas.getContext('2d');
        },
        // ...
        drawOnCanvas(data) {
            // 使用2D上下文进行绘制
            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
            // 根据data绘制内容
        }
    });
    

    请注意,上述示例代码仅为概念性示例,具体实现需要根据您的实际需求进行调整。

    最后,请确保您的Cocos Creator版本与微信小游戏的要求兼容,并遵循微信小游戏的开发规范和限制。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(12条)

报告相同问题?

问题事件

  • 系统已结题 6月14日
  • 已采纳回答 6月6日
  • 创建了问题 6月6日

悬赏问题

  • ¥15 Unity 2022.3.34版本安卓打包apk失败,gradle配置问题,用的是mono2x
  • ¥15 R语言中安装bibliometrix 后运行biblioshiny出现问题
  • ¥20 关于#android#的问题:用开发助手发现找不到控件(autojs)
  • ¥15 dir815漏洞反弹shell失败
  • ¥15 支付宝小程序云函数登录获取user_id失败
  • ¥50 python for 循环速度慢
  • ¥15 CubeMX生成的代码用keil编译有报错
  • ¥15 Stata链式中介效应代码修改
  • ¥15 pip安装PyAV报错
  • ¥15 latex投稿显示click download