【微信小游戏】排行榜概念篇


一、前提

  微信小游戏主打社交玩法,为了丰富社交玩法我们肯定会用到关系链数据来做好友排行帮,群排行榜等功能。本篇主要介绍概念同时划重点,下一篇Cocos Creator中实战。

二、概念

1、1)关系链数据:

  一个微信用户的关系链数据包括两部分:

  1. 该用户好友的用户数据
  2. 该用户所在的某个群的群成员的用户数据。

  2)常用的API:

  1. wx.getFriendCloudStorage() 获取当前用户也玩该小游戏的好友的用户数据
  2. wx.getGroupCloudStorage() 获取当前用户在某个群中也玩该小游戏的成员的用户数据
  3. wx.removeUserCloudStorage() 删除用户托管数据中指定字段的数据
  4. 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)主域

  1. sharedCanvas 只能被绘制到上屏 canvas 上。
  2. 上屏 canvas 不能调用 toDataURL,其 context 不能调用 getImageData。
  3. sharedCanvas 不能调用 toDataURL 和 getContext。
  4. 不能将上屏 canvas 和 sharedCanvas 以任意形式绘制到其他 canvas 上,包括 drawImage、createPattern、texImage2D、texSubImage2D。

  2)开放数据域

  开放数据域只能调用有限的 API,如下所示:

  帧率

  1. requestAnimationFrame()
  2. cancelAnimationFrame()

  Timer

  1. setTimeout()
  2. clearTimeout()
  3. setInterval()
  4. clearInterval()

  触摸事件

  1. wx.onTouchStart()
  2. wx.onTouchMove()
  3. wx.onTouchEnd()
  4. wx.onTouchCancel()
  5. wx.offTouchStart()
  6. wx.offTouchMove()
  7. wx.offTouchEnd()
  8. wx.offTouchCancel()

  画布

  1. wx.createCanvas()

  开放数据域的所有 canvas 只支持 2d 渲染模式

  图片

  1. wx.createImage()

  开放数据域的 Image 只能使用本地或微信 CDN 的图片,不能使用开发者自己服务器上的图片。对于非本地或非微信 CDN 的图片,可以先从主域 wx.downloadFile() 下载图片文件,再通过 wx.postMessage() 把文件路径传给开放数据域去使用。

  开放数据

  1. wx.getFriendCloudStorage()
  2. wx.getGroupCloudStorage()
  3. wx.getUserCloudStorage()
  4. wx.setUserCloudStorage()
  5. wx.removeUserCloudStorage()

  监听主域消息

  1. wx.onMessage()

三、总结

1、如果没有自己的服务器,然而还想做排行榜,那必须用到小游戏的开放数据域,开放数据域与主域之间不能相互require,是一种隔离的状态。

2、开放数据域可通过API获取到好友,群排行数据,获取到数据后,可以将内容绘制到离屏画布。

3、这时主域可以通过开放数据域实例访问离屏画布,然后通过drawImage将离屏画布绘制到上屏画布。

四、最后

 欢迎加入QQ群:418177552