QQ小游戲 關(guān)系鏈數(shù)據(jù)指南

2020-07-15 17:55 更新

一個(gè)QQ用戶(hù)的關(guān)系鏈數(shù)據(jù)包括兩部分: 該用戶(hù)好友的用戶(hù)數(shù)據(jù) 該用戶(hù)所在的某個(gè)群的群成員的用戶(hù)數(shù)據(jù)。 為了豐富游戲的社交玩法,我們提供了獲取關(guān)系鏈數(shù)據(jù)的 API: qq.getFriendCloudStorage() 獲取當(dāng)前用戶(hù)也玩該小游戲的好友的用戶(hù)數(shù)據(jù) qq.getGroupCloudStorage() 獲取當(dāng)前用戶(hù)在某個(gè)群中也玩該小游戲的成員的用戶(hù)數(shù)據(jù) 這兩個(gè) API 的返回結(jié)果都是一個(gè)對(duì)象數(shù)組,數(shù)組的每一個(gè)元素都是一個(gè)表示用戶(hù)數(shù)據(jù)的對(duì)象,其結(jié)構(gòu)如下:

屬性 類(lèi)型 說(shuō)明
openId string 用戶(hù)的 openId
avatarUrl string 用戶(hù)的QQ頭像 url
nickName string 用戶(hù)的QQ昵稱(chēng)
data Object 用戶(hù)的游戲數(shù)據(jù)

用戶(hù)的 游戲數(shù)據(jù) 指的是用戶(hù)的段位、戰(zhàn)績(jī)等游戲業(yè)務(wù)特有的數(shù)據(jù),通過(guò)調(diào)用 qq.setUserCloudStorage() 可以將當(dāng)前用戶(hù)的游戲數(shù)據(jù)托管在QQ后臺(tái)。只有被托管過(guò)數(shù)據(jù)的用戶(hù),才會(huì)被視為 玩過(guò) 該小游戲的用戶(hù),才會(huì)出現(xiàn)在 qq.getFriendCloudStorage() 和 qq.getGroupCloudStorage() 返回的對(duì)象數(shù)組中。 除此之外,我們還提供了以下 API:

  • qq.removeUserCloudStorage() 刪除用戶(hù)托管數(shù)據(jù)中指定字段的數(shù)據(jù)
  • qq.getUserCloudStorage() 獲取當(dāng)前用戶(hù)的托管數(shù)據(jù)

qq.getUserCloudStorage、qq.getFriendCloudStorage() 和 qq.getGroupCloudStorage() 只能在 開(kāi)放數(shù)據(jù)域 中調(diào)用。 qq.setUserCloudStorage() 和 qq.removeUserCloudStorage() 可以同時(shí)在 主域 和開(kāi)放數(shù)據(jù)域中調(diào)用。

開(kāi)放數(shù)據(jù)域

開(kāi)放數(shù)據(jù)域 是一個(gè)封閉、獨(dú)立的 JavaScript 作用域。要讓代碼運(yùn)行在開(kāi)放數(shù)據(jù)域,需要在 game.json 中添加配置項(xiàng) openDataContext 指定開(kāi)放數(shù)據(jù)域的代碼目錄。添加該配置項(xiàng)表示小游戲啟用了開(kāi)放數(shù)據(jù)域,這將會(huì)導(dǎo)致一些 限制

{
  "deviceOrientation": "portrait",
  "openDataContext": "src/myOpenDataContext"
}

同時(shí)還需要在該目錄下創(chuàng)建 index.js 作為開(kāi)放數(shù)據(jù)域的入口文件,其代碼運(yùn)行在開(kāi)放數(shù)據(jù)域。game.js 是整個(gè)游戲的入口文件,其代碼運(yùn)行在 主域。對(duì)應(yīng)以上配置,應(yīng)該有如下的目錄結(jié)構(gòu):

├── src
|   └── myOpenDataContext
|       ├── index.js
|       └── ...
├── game.js
├── game.json
└── ...

src/myOpenDataContext 是 開(kāi)放數(shù)據(jù)域的代碼目錄,除 src/myOpenDataContext 以外是 主域的代碼目錄。

主域和開(kāi)放數(shù)據(jù)域中的代碼不能相互 require。以如下的目錄結(jié)構(gòu)為例:

├── 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')

主域和開(kāi)放數(shù)據(jù)域的通信

開(kāi)放數(shù)據(jù)域不能向主域發(fā)送消息。

主域可以向開(kāi)放數(shù)據(jù)域發(fā)送消息。調(diào)用 qq.getOpenDataContext() 方法可以獲取開(kāi)放數(shù)據(jù)域?qū)嵗?,調(diào)用實(shí)例上的 OpenDataContext.postMessage() 方法可以向開(kāi)放數(shù)據(jù)域發(fā)送消息。

// game.js
const openDataContext = qq.getOpenDataContext()
openDataContext.postMessage({
  text: 'hello',
  year: (new Date()).getFullYear()
})

在開(kāi)放數(shù)據(jù)域中通過(guò) qq.onMessage() 方法可以監(jiān)聽(tīng)從主域發(fā)來(lái)的消息。

// src/myOpenDataContext/index.js
qq.onMessage(data => {
  console.log(data)
  /* {
    text: 'hello',
    year: 2018
  } */
})

展示關(guān)系鏈數(shù)據(jù)

如果想要展示通過(guò)關(guān)系鏈 API 獲取到的用戶(hù)數(shù)據(jù),如繪制排行榜等業(yè)務(wù)場(chǎng)景,需要將排行榜繪制到 sharedCanvas 上,再在主域?qū)?sharedCanvas 渲染上屏。

// src/myOpenDataContext/index.js
const sharedCanvas = qq.getSharedCanvas()


function drawRankList(data) {
  data.forEach((item, index) => {
    // ...
  })
}


qq.getFriendCloudStorage({
  success: res => {
    const data = res.data
    drawRankList(data)
  }
})

sharedCanvas 是主域和開(kāi)放數(shù)據(jù)域都可以訪問(wèn)的一個(gè)離屏畫(huà)布。在開(kāi)放數(shù)據(jù)域調(diào)用 qq.getSharedCanvas() 將返回 sharedCanvas。

// src/myOpenDataContext/index.js
const sharedCanvas = qq.getSharedCanvas()
const context = sharedCanvas.getContext('2d')
context.fillStyle = 'red'
context.fillRect(0, 0, 100, 100)

在主域中可以通過(guò)開(kāi)放數(shù)據(jù)域?qū)嵗L問(wèn) sharedCanvas,通過(guò) drawImage() 方法可以將 sharedCanvas 繪制到上屏畫(huà)布。

// game.js
const openDataContext = qq.getOpenDataContext()
const sharedCanvas = openDataContext.canvas


const canvas = qq.createCanvas()
const context = canvas.getContext('2d')
context.drawImage(sharedCanvas, 0, 0)

sharedCanvas 的寬高只能在主域設(shè)置,不能在開(kāi)放數(shù)據(jù)域中設(shè)置。

// game.js
sharedCanvas.width = 400
sharedCanvas.height = 200

sharedCanvas 本質(zhì)上也是一個(gè)離屏 Canvas,而重設(shè) Canvas 的寬高會(huì)清空 Canvas 上的內(nèi)容。所以要通知開(kāi)放數(shù)據(jù)域去重繪 sharedCanvas。

// game.js


openDataContext.postMessage({
  command: 'render'
})

// src/myOpenDataContext/index.js
openDataContext.onMessage(data => {
  if (data.command === 'render') {
    // ... 重繪 sharedCanvas
  }
})

限制

當(dāng)小游戲啟動(dòng)開(kāi)放數(shù)據(jù)域,即在 game.json 中添加 openDataContext 配置項(xiàng)時(shí)。小游戲環(huán)境會(huì)對(duì)主域和開(kāi)放數(shù)據(jù)域應(yīng)用一些限制。

主域

  1. sharedCanvas 只能被繪制到上屏 canvas 上。

  2. 上屏 canvas 不能調(diào)用 toDataURL,其 context 不能調(diào)用 getImageData。

  3. sharedCanvas 不能調(diào)用 toDataURL 和 getContext。

  4. 不能將上屏 canvas 和 sharedCanvas 以任意形式繪制到其他 canvas 上,包括 drawImage、createPattern、texImage2D、texSubImage2D。

  5. sharedCanvas 的寬高只能在主域設(shè)置

開(kāi)放數(shù)據(jù)域

  1. 不能設(shè)置 sharedCanvas 的寬高 開(kāi)放數(shù)據(jù)域只能調(diào)用有限的 API,如下所示: 幀率
    • requestAnimationFrame()
    • cancelAnimationFrame() Timer
    • setTimeout()
    • clearTimeout()
    • setInterval()
    • clearInterval() 觸摸事件
    • qq.onTouchStart()
    • qq.onTouchMove()
    • qq.onTouchEnd()
    • qq.onTouchCancel()
    • qq.offTouchStart()
    • qq.offTouchMove()
    • qq.offTouchEnd()
    • qq.offTouchCancel() 畫(huà)布
    • qq.createCanvas() 開(kāi)放數(shù)據(jù)域的所有 canvas 只支持 2d 渲染模式 圖片
    • qq.createImage() 開(kāi)放數(shù)據(jù)域的 Image 只能使用本地或QQ CDN 的圖片,不能使用開(kāi)發(fā)者自己服務(wù)器上的圖片。對(duì)于非本地或非QQ CDN 的圖片,可以先從主域 qq.downloadFile() 下載圖片文件,再通過(guò) OpenDataContext.postMessage() 把文件路徑傳給開(kāi)放數(shù)據(jù)域去使用。 開(kāi)放數(shù)據(jù)
    • qq.getFriendCloudStorage()
    • qq.getGroupCloudStorage()
    • qq.getUserCloudStorage()
    • qq.setUserCloudStorage()
    • qq.removeUserCloudStorage() 調(diào)用開(kāi)放數(shù)據(jù)API之前, 需要調(diào)用qq.login()獲取登錄憑證。 監(jiān)聽(tīng)主域消息
    • qq.onMessage()
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)