微信小游戏开发小记

前言

最近因为业务缘由开始接触微信小游戏的开发,踩了一些坑。下面开始写一下关于遇到的一些问题以及解决方法的总结,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 全部,如需转载,请注明出处;

相关文章
相关标签/搜索