- 一个房间2个玩家 玩家b退出房间再重新进入 joinroom必报4005错误
https://developers.weixin.qq.com/minigame/dev/api/game-server-manager/wx.getGameServerManager.html 一个房间2个玩家 玩家b退出房间再重新进入joinroom必报4005错误
2022-05-03 - 微信原生开放域实现排行榜、好友送礼
在使用Cocos Creator制作微信小游戏的时候,基本上都是需要排行榜功能的。 鉴于如果使用Cocos Creator官方提供的WxSubContextView,会增大不少开放域包体。如果本身主域工程的包体已经有点大,并且还不想用分包加载的话,那么可以考虑使用微信提供的API和Canvas渲染来做排行榜系统。这样可以极大的减小开放域包体。一起来试试吧。下面我将分享我自己整理的一份微信原生开放域实现排行榜的工程。其中实现的功能有: 用户授权按钮(位置适配) 上传用户数据 获取好友托管信息、展示好友排行榜(分页展示) 好友互动赠送 工程运行截图如下: [图片] [图片] 主域和子域通信 主域和子域的通信,大家应该都很熟悉,主域和子域的通信是单向的,只能主域向子域发消息,子域不能向主域发消息。在子域(开放域)中,用wx.onMessage进行监听,在主域中发送消息给子域。 [图片] 在子域中监听 [图片] 用户授权按钮(位置适配) 我看见有很多小游戏的用户授权按钮点击位置并没有做好适配,基本就是在一个UI界面点击任何位置都可以进行授权,有时候用户可能会不理解,或者不知道是怎么回事。那么有一个非常明显提示用户登录的按钮,是有必要的。 这里需要注意的是,微信的单位像素并不是标准的游戏设计中的像素单位。 所以要注意单位的转换,把游戏设计中的像素单位转换为微信中的像素单位。 [图片] 上传用户数据 上传用户数据可以直接在主域中调用微信的提供的API,上传用户托管数据 [图片] 获取好友托管信息、展示好友排行榜 主要难点是在子域中,怎么渲染界面。渲染界面用的是Canvas,获取Canvas对象的绘制上下文,进行绘制渲染 [图片] 好友互动 好友互动的话,就要加点击事件了,但是在子域中,怎么添加点击事件。 这里是在Canvas上添加点击事件的监听,然后判断点击的点是否在一个图片大小范围内,判断点击是否有效。有效,则调用微信相关的API取修改好友的互动数据。 [图片] 还有一个注意的一些点: 1.小游戏目录下,新建jsserver目录 [图片] 2.project.config.json中添加 “jsserverRoot”: “jsserver/” 3.game.json中添加 交互模板 [图片] [图片] 完成以上的步骤,在主域中,获取自己的互动数据wx.getUserInteractiveStorage,此处需要解密从微信回传的加密数据。需要云函数调用或者通过服务端处理。 在完成开放数据域代码后,直接该工程目录下,新建build-templates文件夹,并且将开放数据域代码拷贝一份到build-templates/wechatgame下,如图 [图片] 然后构建即可。 完整代码,尽在https://gitee.com/zzhcodes/WxOpenDataProject [图片] 你的关注和在看,是对我最大的鼓励! 我是小周,很高兴能和你一起学习进步!
2020-06-29 - 动物餐厅项目内存优化思路分享
写在前边 本文分享动物餐厅优化内存的经验,几乎无代码,仅阐述思路,比较适用于已经稳定上线的老项目改造。 为什么要优化内存 老项目,可能已经上线一年半载了,随着系统越来越多,资源也越来越多,线上内存越来越吃紧,内存峰值触及红线就会收到内存警告,如果不做处理游戏可能就会被杀死 动物餐厅也面临着这样的窘境,作为爆款微信小游戏,App Store、Google Play 常年热门,更新频率非常高,各种资源日积月累,微信小游戏平台上内存崩溃率曾经高达15%,从此开始了和内存崩溃的斗争 首先展示一下优化成果: [图片] 从上图可以看出,因为内存问题造成的闪退,在我们优化版本更新后,低端机的崩溃率有了非常明显的降低 那么我们是怎么做的? -动物餐厅客户端技术栈现状 编辑器、引擎用的是 Cocos Creator 2.0.10 语言使用 JavaScript 有两个 .fire 场景,一个启动场景,一个游戏主场景 启动场景用来检查更新、加载资源、加载数据 游戏主场景就是游戏主场景 :) 其他界面使用 .prefab 实例化出节点挂载到游戏主场景上 历史原因,资源管理方面比较混乱 -节点池 这个我相信大家应该都有心得,无非就是把使用频次高的节点储藏起来便于复用,这里就不再赘述 -延迟加载资源 即不要一股脑的把资源全加载到内存里 比如上边说到的,界面都是 .prefab 实例化出来节点挂载到游戏主场景上 使用这个界面的时候才会去加载 .prefab,引擎会把 .prefab 和其引用的资源下载下来并加载到内存里 题外话,加载期间最好避免玩家进行其他操作(血淋淋的教训),最简单的就是加个转菊花界面挡住 -释放没用的资源 这些资源包括图片,音频等等 我们做过内存占用成分摸底,发现大部分内存是被图片资源吃掉的,音频也占了不小的一部分,但是一顿平衡以后没有动音频,仅释放 prefab 和其引用的资源 -资源引用计数 资源引用计数的概念大家能搜到很多优秀的文章,这里只说说动物餐厅的做法 早期我们仅对部分动态加载的资源进行了引用计数,但是发现这样会错误的释放没有进行引用计数的资源,后来对所有资源进行了引用计数 实现其实很简单, 正在使用的资源 uuid 容器 resMap 对象 加载资源的方法 loadRes() 实例化 prefab 的方法 autoReleaseInstantiate() 节点销毁时自动释放引用的组件 AutoRelease loadRes() 内部调用引擎加载资源的方法 cc.loader.loadRes() 禁止使用 node.parent = null,node.removeFromParent,node.removeChildren,node.removeAllChildren 等方法移除节点,使用 node.destroy() 替代 禁止使用 cc.instantiate(),使用 autoReleaseInstantiate() 替代 autoReleaseInstantiate() 方法内部调用 cc.instantiate(),同时为实例化出来的节点添加 AutoRelease 组件,内容大概如下 [图片] AutoRelease.js init() 接收一个 prefab 参数保存下来,并获取 prefab 引用的所有资源的 uuid 挨个 resMap[uuid]++ onDestroy() 被引擎调用时 resMap[uuid]-- 禁止使用 autoReleaseInstantiate() 拷贝节点,采用实例化 prefab 的方式替代 当收到内存警告的时候,调用引擎 cc.loader.releaseRes() 释放掉 resMap 中 value 为 0 的资源 这样平衡了时间和空间,内存警告只在微信和 QQ 上有,APP 上动物餐厅的处理方式是定时清理 -遇到的一些问题 问题1 我们知道 .prefab 引用的资源肯定不是同时全部加载完的,我们称他们为子资源 假设这样一个场景,界面 Home 和界面 Garden 都使用了 A.png,Home 已经加载完毕并且显示在了场景上,这时候加载 Garden ,然后 Home 用完了 A 就要释放掉,但是 Garden 还没加载完毕,当 Garden 全部加载成功就会发现 A 被释放掉了,引擎没有处理这种情况 :( ,从而引起一系列奇奇怪怪的问题 处理方式如下 增加了一个加载过程中受保护的子资源 uuid 容器 protectMap 对象 cc.loader.loadRes() 提供了进度回调,加载完一个子资源就计数一个子资源,全部资源成功加载后才释放这些计数 封装了一个 releaseRes 方法,内部调用 cc.loader.releaseRes,protectMap 内没有且 resMap 中计数为 0 的资源才会被释放掉 有加载成功就有加载失败,记得处理加载失败的资源计数哦 题外话,这就是 Uncaught TypeError: Cannot read property '__ONCE_FLAG:load' of null,以及 simple.js Object.fillBuffers Uncaught TypeError: Cannot read property '0' of null 的报错来源 问题2 使用过程中可能会动态替换资源,比如 sprite.spriteFrame,这时候需要处理老资源计数--,新资源计数++ 问题3 可能会出现使用 loadRes() 加载完成后没有立即使用 autoReleaseInstantiate() 的情况,这时候资源是没有计数的,有被释放的风险,我们的做法是不允许这种写法 -降低规格 降低图片的分辨率,是最简单粗暴的优化内存方式 动物餐厅没有采用这种方式 最后一点点 优化需要结合实际项目情况,平衡其他方面的损失,游戏性能指标毕竟不止内存一项,避免出现负优化 by 动物餐厅-狍子
2020-09-29