- 微信小游戏性能优化指南
“小游戏性能优化”专题包含小游戏性能概况、框架原理、评测标准、优化工具与最佳实践等系列文章。内容持续更新,希望能帮助开发者提升游戏性能。 微信小游戏开发者在研发过程中有什么技术疑问或建议,欢迎与我们交流! [图片]
2020-06-28 - 菜鸟教程 - 如何实现 邀请好友送金币
这期菜鸟教程我们会用一个具体的产品方案来为大家解答以下这些问题—— 1. 小游戏基于关系链的互动玩法有哪些? 2. 邀请好友的后续互动, 如何通过关系链互动 和 定向分享能力实现? 3. 开放数据域UI绘制太麻烦了,怎么办? 产品方案 · 在游戏内,定向邀请未注册的特定微信好友加入游戏;(也可以是游戏自定义条件的已注册好友,例如7天未登陆游戏的好友) · 成功邀请后,开发者可监听成功事件。 · 邀请者可获取已邀请的好友信息。 [图片] 案例实现 1 邀请好友 | 获取未玩过该游戏的好友 开发者需要在开放数据域通过 wx.getPotentialFriendList接口获取可能对游戏感兴趣的未注册的好友名单。该接口可以一次获取至多5个非同玩好友,每次拉去都会刷新名单。开发者拿到好友的openid、昵称和头像等数据,然后就可以开始提示玩家邀请啦! [代码]wx.getPotentialFriendList({[代码][代码] [代码][代码]success: (data) => {[代码][代码] [代码][代码]let list = data.list || [];[代码] [代码] [代码][代码]console.log([代码][代码]'getPotentialFriendList'[代码][代码], data);[代码][代码] [代码][代码]}[代码][代码]});[代码] | 向指定用户发起分享 获取到好友数据之后,在开放数据域,通过wx.shareMessageToFriend接口可以给指定好友定向分享。 [代码]wx.shareMessageToFriend({[代码][代码] [代码][代码]openId : [代码][代码]''[代码][代码], [代码][代码]// 这里填写好友的openid[代码][代码] [代码][代码]title : [代码][代码]'快来探索浩瀚星空'[代码][代码],[代码][代码] [代码][代码]imageUrl: [代码][代码]'https://mmocgame.qpic.cn/wechatgame/TKicR7oWel4znvwMdwOpuwoy1ntVB44kT9ZSse2u0xNcO5SaxIS2UwU0GdUfA2Al0/0'[代码][代码]})[代码] | 设置分享参数 wx.shareMessageToFriend的分享参数,只能从主域传入。 故拉起开放数据域前,开发者需要先通过wx.setMessageToFriendQuery 接口设置。目前该接口只允许传入一个参数 shareMessageToFriendScene,并且仅可以在游戏域使用。 [代码]// 设置定向分享参数(这里假设1代表的是邀请新玩家场景值)[代码][代码]wx.setMessageToFriendQuery({[代码][代码] [代码][代码]shareMessageToFriendScene: 1[代码][代码]});[代码] | 监听邀请成功事件 用户发起定向分享之后,在基础库2.9.4以上支持通过接口wx.onShareMessageToFriend监听邀请成功事件(链接待补充),给予邀请者激励。 [代码]wx.onShareMessageToFriend && wx.onShareMessageToFriend((res) => {[代码][代码] [代码][代码]console.log([代码][代码]'wx.shareMessageToFriend'[代码][代码], res);[代码][代码] [代码][代码]let tips = res.success ? [代码][代码]'分享成功'[代码] [代码]: [代码][代码]'分享失败'[代码][代码];[代码] [代码] [代码][代码]wx.showToast({[代码][代码] [代码][代码]title : tips,[代码][代码] [代码][代码]icon : [代码][代码]'none'[代码][代码],[代码][代码] [代码][代码]duration: [代码][代码]2000[代码][代码] [代码][代码]});[代码][代码] [代码][代码]// 这里可触发游戏逻辑[代码][代码]});[代码] | 小结 至此,拉取好友、定向分享、监听成功通知的操作就完成了,几个接口的调用顺序如下,我们通过一个图来简单梳理这里的流程: [图片] 2 新玩家加入游戏,双方领奖励 | STEP1: 接受邀请 新玩家点击卡片进入游戏,开发者可通过 wx.getLaunchOptionsSync接口获取启动时候的信息,返回的对象中会有 query 参数,之前邀请者设置的 shareMessageToFriendScene 就会出现在 query 里了。我们直接判断这个值是否为 1(前文,我们设置了1为邀请新玩家场景值),然后发送事件给开放数据域,表明接收到了邀请。 [代码]wx.onShow((options) => {[代码][代码] [代码][代码]console.log([代码][代码]'onShow options'[代码][代码], options);[代码] [代码] [代码][代码]// 玩家通过被邀请的卡片进入,向子域发送消息,要求修改开放数据域消息[代码][代码] [代码][代码]if[代码] [代码](options && options.query.shareMessageToFriendScene === [代码][代码]'1'[代码] [代码]) {[代码][代码] [代码][代码]this[代码][代码].openDataContext.postMessage({[代码][代码] [代码][代码]event: [代码][代码]'reciveInvite'[代码][代码],[代码][代码] [代码][代码]});[代码][代码] [代码][代码]}[代码][代码]});[代码] | STEP2: 修改卡片分享人的托管数据 敲小黑板了!关键点来了!最多人问就是这里了!分享点进来不知道谁分享的,怎么办? 开放数据域收到 event 为 ‘reciveInvite’ 的消息之后,开发者可通过wx.modifyFriendInteractiveStorage接口修改邀请者的托管数据来做回馈。这个时候需要带上一个特别的参数 quiet: true 来表示修改卡片分享人的数据。设置了quiet:true的互动,开发者无需填入touser,用户侧也无需确认噢。 [代码]wx.modifyFriendInteractiveStorage({[代码][代码] [代码][代码]// 这里定义key“2”代表邀请玩家的数量[代码][代码] [代码][代码]key :[代码][代码]'2'[代码][代码],[代码][代码] [代码][代码]opNum : 1,[代码][代码] [代码][代码]operation: [代码][代码]'add'[代码][代码],[代码][代码] [代码][代码]// 静默修改需要用户通过快捷分享消息卡片进入才有效,代表分享反馈操作,无需填写 toUser,直接修改分享者与被分享者交互数据[代码][代码] [代码][代码]quiet : [代码][代码]true[代码][代码],[代码][代码] [代码][代码]complete:(res) => {[代码][代码] [代码][代码]console.log([代码][代码]'modifyFriendInteractiveStorage'[代码][代码], res);[代码][代码] [代码][代码]}[代码][代码]});[代码] | STEP3: 数据校验 及 记录赠送关系 通过wx.modifyFriendInteractiveStorage我们可以修改卡片分享人的互动型托管数据,但是这个API看起来并没有记录邀请人和被邀请人,只是简单修改卡片分享人的数据,如果我想校验下哪些用户是已经邀请过的,或者想展示邀请记录该怎么做呢? 这里我们需要了解下JSServer: wx.modifyFriendInteractiveData接口在具体写入操作之前会默认执行开发者托管在JSServer上的一段代码,要求开发者使用开发者工具上传文件checkInteractiveData.js。 而在JSServer运行环境下,可以调用wx.getOpenId()、wx.getFriendUserStorage()和wx.setFriendUserStorage()这几个接口,此外还可以拿到用户本人openid:wx.getOpenId()、目标好友openid:toUser和增加的数据opNum,这样除了执行校验,还可以顺带将邀请和被邀请记录写入普通托管数据,如下图所示(JSServer的校验逻辑可以参考本文附上的源码): [图片] || TIPS:游戏过审发布后,记得在工具上将checkInteractiveData.js文件发布上线,校验才会在正式环境生效。否则,修改互动型托管数据也会失败。 [图片] | STEP4: 触发邀请成功后游戏逻辑 按照上面的步骤,互动型托管数据和邀请记录都已经记录起来了。 但这些数据都是在开放数据域才能拿到的,如果想在主域根据这些邀请记录来做发放奖励逻辑该怎么做呢?这里我们在主域提供了wx.getUserInteractiveStorage接口,可以拉取互动性关系链数据。 [代码]// 获取用户的加密交互数据[代码][代码]wx.getUserInteractiveStorage({[代码][代码] [代码][代码]keyList: [[代码][代码]'2'[代码][代码]],[代码][代码] [代码][代码]success: ({cloudID}) => {[代码][代码] [代码][代码]// 该接口拿到的是加密数据,数据解密可以通过开发者自己的后台也可以通过云函数,这里演示云函数[代码][代码] [代码][代码]wx.cloud.callFunction({[代码][代码] [代码][代码]name: [代码][代码]'getUserInteractiveStorage'[代码][代码],[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]userInteractive: wx.cloud.CloudID(cloudID),[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}).then(res => {[代码][代码] [代码][代码]console.log([代码][代码]'cloud getUserInteractiveStorage'[代码][代码], res);[代码][代码] [代码][代码]});[代码][代码] [代码][代码]}[代码][代码]});[代码] 通过上述接口拿到的最终数据如下,代表邀请了3个玩家,开发者根据这个数据就可以给玩家发放奖励了! [代码]{[代码][代码] [代码][代码]"data"[代码][代码]:{[代码][代码] [代码][代码]"kv_list"[代码][代码]:[[代码][代码] [代码][代码]{[代码][代码] [代码][代码]"key"[代码][代码]:[代码][代码]"2"[代码][代码],[代码][代码] [代码][代码]"value"[代码][代码]:[代码][代码]"3"[代码][代码] [代码][代码]}[代码][代码] [代码][代码]][代码][代码] [代码][代码]},[代码][代码] [代码][代码]"openid"[代码][代码]:[代码][代码]"xxxxx"[代码][代码]}[代码] 至此,如何实现邀请好友,双方激励的案例实践讲完啦!而且,我们的开发GG还把上面的示例代码提供给大家,下载换个APPID,做个UI就可以跑咯,源码链接 [图片] 上面的case能力都是在开放数据域实现,但我们有收到很多反馈:在开放数据域做UI界面太难了!! “我只是想绘制一个简单的好友列表,最多加个赠送或者邀请按钮,在开放数据域做UI界面太难了!!” “开放数据域引入一个独立的游戏引擎会占据好多代码包体积” “纯canvas开发真的太麻烦,代码可读性差,事件处理也很麻烦” 这是很多开发者的心声。 为此,开发哥哥们也提供了开放数据域UI绘制的解决方案——轻量级的canvas渲染引擎。 体积小!性能还杠杠的!上面的demo就是用它完成的。 轻量级的canvas渲染引擎 这款轻量级的canvas渲染引擎,它具有以下特点: · 引擎体积很小,压缩之后仅~50kb; · 类Web开发,只需提供XML + CSS即可渲染界面,提高代码可维护性; · 性能强大:长列表滚动可跑满60帧; [图片] | 使用教程: · step 1:克隆本项目到合适的文件夹,引用引擎 [代码]// 通过Git的方式安装[代码][代码]git clone https:[代码][代码]//github.com/wechat-miniprogram/minigame-canvas-engine[代码] [代码]// 引用渲染引擎[代码][代码]import Layout from [代码][代码]'minigame-canvas-engine'[代码] · step 2:为UI界面编写模板和样式 [代码]let template = `[代码][代码]<view >[代码][代码] [代码][代码]<text value=[代码][代码]"hello canvas"[代码][代码]> </text>[代码][代码]</view>[代码][代码]`[代码] [代码]let style = {[代码][代码] [代码][代码]container: {[代码][代码] [代码][代码]width: 200,[代码][代码] [代码][代码]height: 100,[代码][代码] [代码][代码]backgroundColor: [代码][代码]'#ffffff'[代码][代码],[代码][代码] [代码][代码]justContent: [代码][代码]'center'[代码][代码],[代码][代码] [代码][代码]alignItems: [代码][代码]'center'[代码][代码],[代码][代码] [代码][代码]},[代码][代码] [代码][代码]testText: {[代码][代码] [代码][代码]color: [代码][代码]'#ff0000'[代码][代码],[代码][代码] [代码][代码]width: 200,[代码][代码] [代码][代码]height: 100,[代码][代码] [代码][代码]lineHeight: 100,[代码][代码] [代码][代码]fontSize: 30,[代码][代码] [代码][代码]textAlign: [代码][代码]'center'[代码][代码],[代码][代码] [代码][代码]}[代码][代码]}[代码] · step 3:调用渲染API,执行真正的渲染 [代码]// 将模板和样式传给渲染引擎,渲染引擎会生成布局树和渲染树等,准备渲染到canvas上面[代码][代码]Layout.init(template, style);[代码][代码] [代码] [代码]// sharedContext自行创建[代码][代码]Layout.layout(sharedContext);[代码] [代码]/**[代码][代码] [代码][代码]* 设置sharedCancas在主域绘制的物理尺寸和位置信息,这一步非常重要,[代码][代码] [代码][代码]* 因为子域渲染引擎并不关心外部使用的引擎是什么,而是自己监听触摸事件来进行事件处理,[代码][代码] [代码][代码]* 因此需要拿到真实的物理尺寸、位置信息来执行事件处理。[代码][代码] [代码][代码]*/[代码][代码]Layout.updateViewPort({[代码][代码] [代码][代码]width : 200,[代码][代码] [代码][代码]height: 100,[代码][代码] [代码][代码]x : 100,[代码][代码] [代码][代码]y : 100[代码][代码]});[代码] · step 4:效果预览 [图片] || TIPS: 详细的教程可以查看文档; 为了方便调试,还可以使用在线编辑功能; 上面的邀请好友获得激励的demo示例,也是用这个canvas渲染引擎实现的喔。 对定向分享奖励还有什么疑问或者经验分享?希望了解哪些方面的实践教程?欢迎在评论区留言。
2019-12-09