一、前提
微信小游戏主打社交玩法,为了丰富社交玩法我们肯定会用到关系链数据来做好友排行帮,群排行榜等功能。本篇主要介绍概念同时划重点,下一篇Cocos Creator中实战。
二、概念
1、1)关系链数据:
一个微信用户的关系链数据包括两部分:
- 该用户好友的用户数据
- 该用户所在的某个群的群成员的用户数据。
2)常用的API:
- wx.getFriendCloudStorage() 获取当前用户也玩该小游戏的好友的用户数据
- wx.getGroupCloudStorage() 获取当前用户在某个群中也玩该小游戏的成员的用户数据
- wx.removeUserCloudStorage() 删除用户托管数据中指定字段的数据
- wx.getUserCloudStorage() 获取当前用户的托管数据
注意:
wx.getUserCloudStorage、wx.getFriendCloudStorage() 和 wx.getGroupCloudStorage() 只能在 开放数据域
中调用。
wx.setUserCloudStorage() 和 wx.removeUserCloudStorage() 可以同时在 主域
和开放数据域中调用。
2、开放数据域
开放数据域
是一个封闭、独立的 JavaScript 作用域。要让代码运行在开放数据域,需要在 game.json 中添加配置项 openDataContext
指定开放数据域的代码目录。
{ "deviceOrientation": "portrait", "openDataContext": "src/myOpenDataContext" }
同时还需要在该目录下创建 index.js 作为开放数据域的入口文件,其代码运行在开放数据域。game.js 是整个游戏的入口文件,其代码运行在 主域
。对应以上配置,应该有如下的目录结构:
├── src | └── myOpenDataContext | ├── index.js | └── ... ├── game.js ├── game.json └── ...
src/myOpenDataContext 是 开放数据域的代码目录
,除 src/myOpenDataContext 以外是 主域的代码目录
。
主域和开放数据域中的代码不能相互 require。以如下的目录结构为例:
├── src | └── myOpenDataContext | ├── index.js | ├── util.js | └── ... ├── lib | └── render.js └── game.js
在 game.js 中不能 require(‘src/myOpenDataContext/util‘)
在 src/myOpenDataContext/index.js 中不能 require(‘../../lib/render.js‘)
3、主域和开放数据域的通信
开放数据域不能向主域发送消息。
主域可以向开放数据域发送消息。调用 wx.getOpenDataContext() 方法可以获取开放数据域实例,调用实例上的 OpenDataContext.postMessage() 方法可以向开放数据域发送消息。
// game.js let openDataContext = wx.getOpenDataContext() openDataContext.postMessage({ text: ‘hello‘, year: (new Date()).getFullYear() })
在开放数据域中通过 wx.onMessage() 方法可以监听从主域发来的消息。
// src/myOpenDataContext/index.js wx.onMessage(data => { console.log(data) /* { text: ‘hello‘, year: 2018 } */ })
4、展示关系链数据
如果想要展示通过关系链 API 获取到的用户数据,如绘制排行榜等业务场景,需要将排行榜绘制到 sharedCanvas
上,再在主域将 sharedCanvas 渲染上屏。
// src/myOpenDataContext/index.js let sharedCanvas = wx.getSharedCanvas() function drawRankList (data) { data.forEach((item, index) => { // ... }) } wx.getFriendUserGameData({ success: res => { let data = res.data drawRankList(data) } })
sharedCanvas 是主域和开放数据域都可以访问的一个离屏画布。在开放数据域调用 wx.getSharedCanvas() 将返回 sharedCanvas。
// src/myOpenDataContext/index.js let sharedCanvas = wx.getSharedCanvas() let context = sharedCanvas.getContext(‘2d‘) context.fillStyle = ‘red‘ context.fillRect(0, 0, 100, 100)
在主域中可以通过开放数据域实例访问 sharedCanvas,通过 drawImage() 方法可以将 sharedCanvas 绘制到上屏画布。
// game.js let openDataContext = wx.getOpenDataContext() let sharedCanvas = openDataContext.canvas let canvas = wx.createCanvas() let context = canvas.getContext(‘2d‘) context.drawImage(sharedCanvas, 0, 0)
5、限制
当小游戏启动开放数据域,即在 game.json 中添加 openDataContext 配置项时。小游戏环境会对主域和开放数据域应用一些限制。
1)主域
- sharedCanvas 只能被绘制到上屏 canvas 上。
- 上屏 canvas 不能调用 toDataURL,其 context 不能调用 getImageData。
- sharedCanvas 不能调用 toDataURL 和 getContext。
- 不能将上屏 canvas 和 sharedCanvas 以任意形式绘制到其他 canvas 上,包括 drawImage、createPattern、texImage2D、texSubImage2D。
2)开放数据域
开放数据域只能调用有限的 API,如下所示:
帧率
Timer
触摸事件
- wx.onTouchStart()
- wx.onTouchMove()
- wx.onTouchEnd()
- wx.onTouchCancel()
- wx.offTouchStart()
- wx.offTouchMove()
- wx.offTouchEnd()
- wx.offTouchCancel()
画布
开放数据域的所有 canvas 只支持 2d
渲染模式
图片
开放数据域的 Image 只能使用本地或微信 CDN 的图片,不能使用开发者自己服务器上的图片。对于非本地或非微信 CDN 的图片,可以先从主域 wx.downloadFile() 下载图片文件,再通过 wx.postMessage() 把文件路径传给开放数据域去使用。
开放数据
- wx.getFriendCloudStorage()
- wx.getGroupCloudStorage()
- wx.getUserCloudStorage()
- wx.setUserCloudStorage()
- wx.removeUserCloudStorage()
监听主域消息
三、总结
1、如果没有自己的服务器,然而还想做排行榜,那必须用到小游戏的开放数据域,开放数据域与主域之间不能相互require,是一种隔离的状态。
2、开放数据域可通过API获取到好友,群排行数据,获取到数据后,可以将内容绘制到离屏画布。
3、这时主域可以通过开放数据域实例访问离屏画布,然后通过drawImage将离屏画布绘制到上屏画布。
四、最后
欢迎加入QQ群:418177552