微信小遊戲開發小記

前言

最近因爲業務緣由開始接觸微信小遊戲的開發,踩了一些坑。下面開始寫一下關於遇到的一些問題以及解決方法的總結,javascript


1、開放數據域繪製圖片問題

在DOM 環境中使用Canvans 繪製圖片咱們通常是使用以下的方式:html

var img = document.getElementById('img');
ctx.drawImage(img, 10, 10);
複製代碼

drawImage 的第一個參數能夠用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement做爲參數,可是在開放數據域下不存在DOM 操做,咱們須要使用以下的方式去繪製圖片;java

let pic = wx.createImage(); 
pic.src = url;
// 若是是網絡圖片,則需加載完成後繪製
// pic.onload = () => {
  ctx.drawImage(pic, 10, 10);
// }
複製代碼

2、開放數據域性能問題

因爲開放域不能向主域發送數據,傳統上的思路是主域須要刷新ShareCanvas並繪製到主屏上,但這樣就會致使性能上的開銷過大,僅僅用來繪製排行榜的話是十分不明智的作法,Egret 有一個髒渲染的概念,若是頁面沒有「髒」,便是沒有變化的元素,則不會從新渲染Canvans ,從而減小了重繪次數,優化了渲染性能,具體的實現思路以下:node

let requestAnimationFrameID; // 記錄requestAnimationFrame的ID
let isDirty = true; // 標誌是否爲髒
/** * 每次渲染時,判斷是否「髒」了,如果,則從新渲染 */
function render() {
  if (isDirty) {
    context.setTransform(1, 0, 0, 1, 0, 0); // 座標系復位
    context.clearRect(0, 0, sharedCanvas.width, sharedCanvas.height); // 清除 Canvans 畫布
    drawElements();  //繪製排行榜,或者其餘元素
    isDirty = false;
  }
  requestAnimationFrame(render);
}
複製代碼

3、UI 同步問題

微信小遊戲有一個十分坑的地方:4M的限制。當咱們須要繪製排行榜但又須要讓ui 與主域一致的時候就會出現很尷尬的情況:若是將ui代碼在開放域和主域都放一份,這會讓體積大大增長,若是使用的是遊戲框架,同步繪製代碼的難度也會增長。git

那麼,咱們能夠怎麼解決這個問題呢?github

個人實現思路是,開放域的存在目前也只是獲取好友或羣共玩好友的關係數據,對於大多數遊戲,只在繪製排行榜傷上有用。所以,排行榜能夠僅繪製關係數據,即,只繪製頭像、排行這一類數據,繪製時對尺寸進行比例縮放,而背景則在主域進行繪製,而後再把排行榜墊在背景上。這種方法僅適用於只繪製不那麼複雜的排行榜的需求,對於須要繪製更復雜的界面的功能來講仍是雞肋的,還沒有見到或想出一個更好的方法。數據庫


4、客服消息回回復圖片功能

很多的小遊戲都有客服功能的需求(emmm,好比回覆公衆號圖片引導關注),可是微信的客服系統是不支持回覆圖片的,這個時候就須要本身接入客服功能。微信的發送圖片信息的body 格式以下:json

"touser":"OPENID",
    "msgtype":"image",
    "image":
    {
      "media_id":"MEDIA_ID"
    }
}
複製代碼

具體實現步驟以下:小程序

  1. 新增臨時素材 當咱們想向用戶發送一張圖片時,並不能爲所欲爲地使用任意圖片地址,如上json所示,微信只提供一個mediaid,這個mediaid是咱們調用新增臨時素材接口提交到微信服務器上以後,返回的一個圖片標識,接口以下:
https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
複製代碼

參數說明: access_token: 調用接口憑證 type:媒體類型,固定填寫爲 image media:form-data中媒體文件標識,有filename、filelength、content-type等信息api

而後咱們須要實現一個能夠上傳圖片的頁面,node端接收併發送到微信服務器上,若是成功獲取到mediaid以後咱們就能夠存放在數據庫或緩存上對應appid 的地方以便後續發送圖片使用

let token = wechat.getMiniAccessToken(); // 本身實現獲取當前小程序/小遊戲的access token的函數,appid 要對應,不然mediaid是不會回覆到用戶的
const options = {
  url: `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${token.access_token}&type=image`,
  formData: body.fields,
};

request.post(options, (err, res, data) => {
  // 將回傳的對象中的mediaid 對應appid存放
})
複製代碼
  1. 接收用戶發來的消息

這一步咱們須要先配置好服務器,參考微信服務器接入指引這篇文章,須要注意的是,只有在驗證url是否合法的狀況下,纔會帶有echostr 參數,以此咱們能夠判斷當前請求是否爲服務器驗證,若是帶有echostr 參數,咱們只須要在確認簽名無誤以後,把echostr 原樣返回就能夠了。若是沒有echostr參數,則是微信轉發過來的用戶發來的消息,此時咱們就要進入下一步去發送圖片了。

const {
    signature, timestamp, nonce, echostr,
  } = this.query;
  const { body } = this.request;
  if (echostr) { // 用於配置客服服務器使用
    const result = wechat.checkSign(timestamp, nonce, signature); // 校驗簽名是否正確
    this.body = result ? echostr : 'err signature'; 
  } else {
    wechat.sengMsg(body); // 進入下一步發送圖片
    this.body = 'success';
  }
複製代碼
  1. 向用戶發送圖片

上一步中咱們接收到微信轉發過來的用戶消息,具體格式能夠參考微信客服消息 這篇文章,咱們能夠獲取到發送過來用戶,只須要請求微信的接口,就能夠把消息推送給該用戶了。

const mediaId = '須要發送的圖片的mediaid';
  let token = wechat.getMiniAccessToken(); // 當前小程序/小遊戲的access token
  const options = {
    url: `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token.access_token}`,
    body: {
      touser: data.FromUserName, // 須要發送的用戶
      msgtype: 'image',
      image: {
        media_id: mediaId,
      },
    },
    json: true,
  };
  request.post(options, (err, res, data) => {
    // 發送以後的處理函數
  });
複製代碼

結語

筆者對於微信小遊戲也只能算是剛入門,以上內容也只是幾天開發完以後的一些經驗,不算成熟,若有錯誤,但願指正,互相成長,謝謝。

以上內容歸本人EvontGoh 全部,如需轉載,請註明出處;

相關文章
相關標籤/搜索