微信小游戏 - Canvas/WebGL Demo 移植
2018-02-12 15:30
120 查看
这是个人关于微信小游戏系列文章的第一篇,在这系列文章里会描述 ——
如何把一些 Canvas/WebGL Demo 移植到小游戏环境并支持双端运行;
对小游戏在 Android 平台的运行时架构进行分析;
通过对移植的 Canvas/WebGL Demo 在小游戏和 Chrome for Android 浏览器上做 Benchmarking,对 H5 游戏 vs 小游戏的渲染性能进行对比和分析;
移植的代码已经上传到 GitHub,读者可以自行下载运行测试。
上图从左至右分别是:
Canvas Bitmap,修改自 GUIMark3 Bitmap,类似雷电的小游戏,多个小位图的重复绘制,主要测试 Canvas.drawImage 的性能,跟微信开发工具自带的样例游戏类似;
Canvas Compute,修改自 GUIMark3 Compute,模拟鸟群的运动,包含大量的物理运动计算,实际上是测试 JavaScript 的计算性能;
WebGL Compute,Canvas Compute 的 WebGL 版本,用 WebGL 绘制点取代 Canvas 绘制短线段;
WebGL Aqua,修改自 WebGL Aquarium,绘制的场景有一定的复杂度,包含了约 30 个模型;
移植过程中自己写了一些方便双端运行的适配代码(wxhelper.js),示例如下。
注意规范里面的 performance.now() 是返回微秒精度,但是以毫秒为单位的浮点数值,而小游戏的 API 定义是返回微秒为单位,并且实机环境跟 DevTools 环境还不一样,DevTools 环境估计就是调用浏览器本身的 API,返回的是毫秒为单位的值,这算是踩到的第一个坑,上面的适配代码统一返回毫秒单位。
在小游戏环境中,只允许有一个占据全屏幕的主 Canvas,如果使用微信提供的 Adapter,这个 Canvas 会事先创建并通过 window.canvas 引用。
因为在小游戏环境里面,每个 JavaScript 文件都是一个模块,里面包含的方法和变量不会自动包括在全局对象下面,如果我们需要跟浏览器保存一致的行为,就需要将对外的 API 显式地导出到全局变量。比如:
上面的示例代码可以把 Vector3D 在浏览器和小游戏环境都导出到全局对象下面,虽然在浏览器环境下是多余的。当浏览器对 ES6 Module 的支持完善后,理论上我们可以使用统一的模块管理方式来处理浏览器和小游戏环境的模块 API 的导出/导入的问题。
如何把一些 Canvas/WebGL Demo 移植到小游戏环境并支持双端运行;
对小游戏在 Android 平台的运行时架构进行分析;
通过对移植的 Canvas/WebGL Demo 在小游戏和 Chrome for Android 浏览器上做 Benchmarking,对 H5 游戏 vs 小游戏的渲染性能进行对比和分析;
Canvas/WebGL Demo
为了做性能对比,一共移植了四个 Demo,这些 Demo 常用于浏览器自身的 Canvas/WebGL 性能测试,包括 GUIMark3 和 WebGL Aquarium。移植的代码已经上传到 GitHub,读者可以自行下载运行测试。
上图从左至右分别是:
Canvas Bitmap,修改自 GUIMark3 Bitmap,类似雷电的小游戏,多个小位图的重复绘制,主要测试 Canvas.drawImage 的性能,跟微信开发工具自带的样例游戏类似;
Canvas Compute,修改自 GUIMark3 Compute,模拟鸟群的运动,包含大量的物理运动计算,实际上是测试 JavaScript 的计算性能;
WebGL Compute,Canvas Compute 的 WebGL 版本,用 WebGL 绘制点取代 Canvas 绘制短线段;
WebGL Aqua,修改自 WebGL Aquarium,绘制的场景有一定的复杂度,包含了约 30 个模型;
代码移植过程
总的来说移植并不算太困难,WebGL Aquarium 本身包含了大量的 DOM 元素和利用 DOM 来加载脚本和图片,所以花的时间比较长,其它页面只有很少 DOM 元素和 DOM 操作的,移植起来还是很简单,当然这里只包括主体内容的渲染部分,其它如 HUD,输入事件处理,音频播放等并没有包括在内,如果原来的页面是使用 DOM 做 HUD 的,可能会比较麻烦。另外,如果先开发小游戏再移植到浏览器上运行,理论上应该会更简单。移植过程中自己写了一些方便双端运行的适配代码(wxhelper.js),示例如下。
检查是否是小游戏运行环境
let WX_GAME_ENV = typeof wx !== 'undefined'; let WX_GAME_DEVTOOLS = false; let SystemInfo = null; if (WX_GAME_ENV) { SystemInfo = wx.getSystemInfoSync(); if (SystemInfo.platform == "devtools") WX_GAME_DEVTOOLS = true; }
Performance.now()
function Now() { if (WX_GAME_ENV) { if (WX_GAME_DEVTOOLS) return wx.getPerformance().now(); else return wx.getPerformance().now() / 1000; } else { return performance.now(); } }
注意规范里面的 performance.now() 是返回微秒精度,但是以毫秒为单位的浮点数值,而小游戏的 API 定义是返回微秒为单位,并且实机环境跟 DevTools 环境还不一样,DevTools 环境估计就是调用浏览器本身的 API,返回的是毫秒为单位的值,这算是踩到的第一个坑,上面的适配代码统一返回毫秒单位。
创建 Image 对象
function CreateImage() { if (WX_GAME_ENV) { return wx.createImage(); } else { return new Image(); } }
获取主 Canvas 的引用
let MainCanvas = null; function GetMainCanvas(domId) { function GetMainCanvasImpl(domId) { if (WX_GAME_ENV) { if (window != null && window.canvas != null) return window.canvas; else return wx.createCanvas(); } else { return document.getElementById(domId); } } if (MainCanvas != null) return MainCanvas; MainCanvas = GetMainCanvasImpl(domId); return MainCanvas; }
在小游戏环境中,只允许有一个占据全屏幕的主 Canvas,如果使用微信提供的 Adapter,这个 Canvas 会事先创建并通过 window.canvas 引用。
全局对象
在浏览器环境里面,window 是全局对象,而在小游戏环境里面 GameGlobal 才是全局对象,下面的代码演示了如何在小游戏环境里面模拟 window 全局对象,我们可以在 GameGlobal 下创建一个 window 属性并让它引用自身。if (typeof window !== 'undefined') { window.wxhelper = wxhelper; } else if (typeof GameGlobal !== 'undefined') { GameGlobal.wxhelper = wxhelper; GameGlobal.window = GameGlobal; window.top = GameGlobal.parent = window; } else { console.log("Cannot find any global object!"); }
因为在小游戏环境里面,每个 JavaScript 文件都是一个模块,里面包含的方法和变量不会自动包括在全局对象下面,如果我们需要跟浏览器保存一致的行为,就需要将对外的 API 显式地导出到全局变量。比如:
// Vector3D.js window.Vector3D = function Vector3D(x, y, z){ this.x = x || 0; this.y = y || 0; this.z = z || 0; } // Boid.js Boid.ZERO = new Vector3D(0, 0, 0);
上面的示例代码可以把 Vector3D 在浏览器和小游戏环境都导出到全局对象下面,虽然在浏览器环境下是多余的。当浏览器对 ES6 Module 的支持完善后,理论上我们可以使用统一的模块管理方式来处理浏览器和小游戏环境的模块 API 的导出/导入的问题。
相关文章推荐
- 『教程』微信小游戏开发(教程+Demo+跳坑)canvas
- 微信小程序学习用demo推荐:微信涂鸦、canvas学习
- 【开源】微信小程序、小游戏以及 Web 通用 Canvas 渲染引擎 - Cax
- 微信小游戏canvas画布拖动图片
- 微信小程序学习用demo推荐:微信涂鸦、canvas学习
- 微信小游戏开发入门(二)-用CocosCreator官方Demo生成微信小游戏
- 微信小程序学习用demo推荐:微信涂鸦:canvas学习
- 【猪猪-前端】微信打飞机高质量Demo,学习HTML5+Canvas技术编写,下载即可使用,注释齐全。
- 微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
- 微信小程序canvas:各类图表相关组件+Demo源码
- 微信小游戏「跳一跳」技术手段高分秘籍实现
- m3u8编码视频webgl、threejs渲染视频纹理demo
- [颓废] 改某人的WebGL light mapping demo并9xSSAA
- Android版微信跳一跳小游戏利用技术手段达到高分的操作方法
- 微信小程序:支付系列专辑(开发指南+精品Demo)
- js H5 canvas投篮小游戏
- HTML5 Canvas,WebGL,CSS Shaders,GLSL的暧昧关系
- 微信小游戏---猜拳游戏
- JavaScript操作canvas制作前端H5小游戏——Flappy Bird
- 微信小程序热点云笔记demo 开源总结