前言

这是一次利用 three.js 开发微信小游戏的尝试,并不能算作是教程,只能算是一篇笔记吧。

微信 WeChat 6.6.1 开始引入了微信小游戏,初期上线了一批质量相当不错的小游戏。我在查阅各处的文章时候,发现其中有几款是基于 three.js 开发的,目前火爆朋友圈的《跳一跳》就是其中之一。这引起了我的注意,想起几年前也做过不少 WebGL 的尝试,于是禁不住想要弄到微信小游戏平台上试试。

准备工作

  1. 最新版本的 three.js
  2. 首先应该具有一定的 three.js 开发经验,有之前写过的简单演示代码;
  3. 最新版本的“微信开发者工具”。

另外补充一点:需要足够的耐心,微信开发者工具问题多多,编辑器也各种问题,我是使用 WebStorm 来编写代码,您不妨也试试。遇到奇怪的问题的时候,可能需要多启动几次开发者工具,非常令人恼火。

找一个之前的 WebGL 演示

我随便找了一个很久以前做过的演示代码,如下:

(无法嵌入,如要查看请看原文)可以拖动旋转,滚轮缩放

利用 three.js 开发微信小游戏的尝试​indienova.com

创建微信小游戏项目

好啦,现在可以进入开发者工具尝试移植了。

首先,创建一个标准的小游戏项目。

选择“小游戏”项目进行创建,并选择一个空的目录作为项目目录

点击“确定”就会打开一个模板项目,是一个射击游戏,大致的结构如下:

├── game.js
├── game.json
├── project.config.json
├── README.md
├── js
| ├── databus.js
| ├── main.js
| ├── base
| | ├── animation.js
| | └── ...
| ├── libs
| | ├── symbol.js
| | └── weapp-adapter.js
| ├── npc
| | └── enemy.js
| ├── player
| | ├── bullet.js
| | └── ...
| └── runtime
| ├── background.js
| └── ...
├── audio
| ├── bgm.mp3
| └── ...
└── images
├── Common.png
└── ...

基于这个模板,我们可以将不需要的内容暂时删除,以便跑我们自己的项目。其中,射击游戏相关的内容都可以移除了,但是我们要保留一些关键的代码和配置文件,清理以后,大概会是这个样子:

├── game.js
├── game.json
├── project.config.json
├── README.md
├── js
| ├── main.js
| └── libs
| ├── symbol.js
| └── weapp-adapter.js
└── images
  1. 其中,images 目录里面放置我们需要使用到的图片,在这个例子中,我放了粒子图片和 indienova Logo 图片在里面;
  2. 将我们必然会用到的 three.js(使用 three.min.js 也可以,但是后面需要修改这个文件,所以建议使用没有 minified 的版本)放入 js/libs
  3. 如果有其它资源,比如音频文件什么的,也可以自建目录放进去;
  4. 然后需要修改一下配置文件,简单的说,只要修改 project.config.json 中的 projectname 即可;
  5. 保留 game.js 不变,这个是入口,会引入 main.js 并执行;
  6. main.js 清空,我们的新代码会在这里完成。

我们还保留了两个 js 文件,libs 中的 symbol.jsweapp-adapter.js。这里需要注意的是 weapp-adapter.js 很重要,官方解释如下:

小游戏的运行环境在 iOS 上是 JavaScriptCore,在 Android 上是 V8,都是没有 BOM 和 DOM 的运行环境,没有全局的 document 和 window 对象。因此当你希望使用 DOM API 来创建 Canvas 和 Image 等元素的时候,会引发错误。
…………
这些使用 wx API 模拟 BOM 和 DOM 的代码组成的库称之为 Adapter。顾名思义,这是对基于浏览器环境的游戏引擎在小游戏运行环境下的一层适配层,使游戏引擎在调用 DOM API 和访问 DOM 属性时不会产生错误。Adapter 是一个抽象的代码层,并不特指某一个适配小游戏的第三方库,每位开发者都可以根据自己的项目需要实现相应的 Adapter。官方实现了一个 Adapter 名为 weapp-adapter, 并提供了完整的源码,供开发者使用和参考。

…………

除此之外 weapp-adapter 还模拟了以下对象和方法:

document.createElement
canvas.addEventListener
localStorage
Audio
Image
WebSocket
XMLHttpRequest
等等...

需要强调的是,weapp-adapter 对浏览器环境的模拟远不完整的,仅仅只针对游戏引擎可能访问的属性和调用的方法进行了模拟,也不保证所有游戏引擎都能通过 weapp-adapter 顺利无缝接入小游戏。直接将 weapp-adapter 提供给开发者,更多地是作为参考,开发者可以根据需要在 weapp-adapter 的基础上进行扩展,以适配自己项目使用的游戏引擎。

原文请参阅:这里

可见,微信团队已经为我们开发游戏做好了一些准备,比如露出的 canvas,我们到时候直接拿来使用就是。

将之前的代码移植到项目中

开始将之前写好的代码移植过来,注意由于要使用 ES 6(EMCAScript 6)标准,所以之前的代码可能要做相应的调整,不过大部分都是语法的调整,有一些方法的使用需要增加 bind(this),具体的还请大家参阅我们提供的链接地址,就算不看书,随便尝试一下也能很快有所了解。

新的 main.js 的主体代码看起来是这样:

import * as THREE from 'libs/three.js'

let ctx   = canvas.getContext('webgl')

let scene
let renderer // ... 其它变量/常量 ... /**
* 游戏主函数
*/
export default class Main {
constructor() {
this.start()
} start() {
// 初始化
scene = new THREE.Scene()
renderer = new THREE.WebGLRenderer({ context: ctx }) //... 其它代码块 ... // 开始循环
this.loop()
} // UPDATE 更新
update() {
// ... 数据更新代码块 ...
} // RENDER 渲染
render() {
// ... 渲染代码块 ...
} // 实现游戏帧循环
loop() {
this.update()
this.render() window.requestAnimationFrame( this.loop.bind(this), canvas )
}
}

一些要点:

由于微信已经为我们准备好了的 canvas,所以我们无需自己再进行创建,只需要取得的 canvascontext 就可以了,这里我们使用的不是 2d,而是 webgl

let ctx = canvas.getContext('webgl')

然后我们在创建 WebGLRenderer 的时候,直接使用这个 context 就可以了。

renderer  = new THREE.WebGLRenderer({ context: ctx })

这两点做到了,基本上就不会有太大问题了。

一切正常的话,开发者工具里面应该就能跑得起来了。

能跑起来并不算完,还需要真机测试

真机调试

真机调试不复杂,微信开发者工具提供了真机预览功能,只要点一下“预览”,就会上传代码,并生成二维码供测试。

https://mp.weixin.qq.com/a/~~KXw-v1yT0Xw~q6neR3F6N1Q9g8Uzb0yOVA~~ (二维码自动识别)

开发者用微信扫描这个二维码,就可以打开测试。

如果您没有修改过 three.js 源文件,那么很有可能只看到一个黑屏。

还好,微信小游戏提供了一个调试开关,我们可以选择打开调试:

然后再次扫码进入,就可以查看调试信息了:

可以清晰的得知,createElementNS 不被支持,那么我们可以将所有 createElementNS 改为 createElement(注意,这只是暂时解决方案,此方法并不是理想方案,我们以后应该会有更好的解决方法,通过修改 adapter 应该就可以减少 three.js 源文件的修改。)

document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
// 改为 ==>
document.createElement( 'canvas' );

不止这一处,而且也不止是针对 canvas 的创建,还有针对 img 的创建,可以都修改掉。

另外由于真机上跑的是 OpenGL ES 1.x/2.x/3.x,所以还有一句要处理:

var version = parseFloat( /^WebGL\ ([0-9])/.exec(gl.getParameter(gl.VERSION))[ 1 ] );
// 改为 ==>
var version = parseFloat( /^(WebGL|OpenGL ES)\ ([0-9])/.exec(gl.getParameter(gl.VERSION))[ 1 ] );

这样改过后,重新再尝试一下看,是不是已经可以了?

2018-01-08 更新

临时解决方案使用后,我后来尝试修改 weapp-adapter.js,就不需要再对 three.js 进行修改了:

createElementNS: function createElementNS(nameSpace, tagName) {
return this.createElement(tagName)
}

方法很简单:我们在 document 的定义中添加 createElementNS,然后忽略掉 NameSpace 即可。

结束语

好了,简单的介绍了一下怎么利用 three.js 开发微信小游戏,这并不是一篇教程,只是在目前信息和资料不完善情况下的一种尝试,也希望大家一起参与到开发和研究中来,互相交流。

欢迎加入我们的小组:微信小游戏小组

微信小游戏 | indienova 独立游戏​indienova.com

源代码

为了方便大家参考,特提供源代码。其中包括一个微信小游戏项目和原始的 WebGL 项目。

Github 源代码下载

eastecho/WeChatGame-three-js​github.com

参考链接

这几天研究这部分内容的时候,遇到不少奇怪的问题,这部分内容又很难依靠 Google 和 StackOverflow 来解决,还好找到了交流的 QQ 群,以及群中成员的交流心得,才算完成了这次尝试。

其它相关链接

请先阅读:微信小游戏官方文档

目前,Cocos、Egret、Laya 已经完成了自身引擎及其工具对小游戏的适配和支持,访问对应的官方文档可以更快地接入小游戏的开发

您可能感兴趣的

原文链接:https://zhuanlan.zhihu.com/p/32648805

【转】利用 three.js 开发微信小游戏的尝试的更多相关文章

  1. 使用Laya引擎开发微信小游戏(上)

    本文由云+社区发表 使用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏. 作者:马晓东,腾讯前端高级工程师. 微信小游戏的推出也快一年时间了,在IEG的游戏运营活动中,也出现 ...

  2. 用Vue.js开发微信小程序:开源框架mpvue解析

    前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...

  3. 使用Laya引擎开发微信小游戏

    在支持微信小游戏的游戏引擎中,Cocos,Egret,Laya都对小游戏的开发提供了很多强大的支持.前段时间正好抽空研究了一下这块的内容,现做一个总结,针对如何使用Laya引擎开发微信小游戏给大家做一 ...

  4. MPVUE - 使用vue.js开发微信小程序

    MPVUE - 使用vue.js开发微信小程序 什么是mpvue? mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架.框架提供了完整的 Vue.js 开发体验,开发 ...

  5. 使用Laya引擎开发微信小游戏(下)

    本文由云+社区发表 6. 动画 6.1 创建伞兵对象 在src目录下创建一个新目录role,用来存放游戏中角色. 在role里创建一个伞兵Soldier.ts对象文件. module role{ ex ...

  6. Egret白鹭开发微信小游戏排行榜功能

    推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 我的个人博客 最近事情特别多,今天终于实现了排行榜功能,记录下来大家一起学习学习. 一.调用默认排行榜 首先我们需要了解: 1.白鹭开 ...

  7. Egret白鹭开发微信小游戏分享功能

    今天给大家分享一下微信分享转发功能,话不多说,直接干 方法一: 1.在egret中打开Platfrom.ts文件,添加代码如下(当然,你也可以直接复制粘贴) /** * 平台数据接口. * 由于每款游 ...

  8. Egret白鹭开发微信小游戏程序跳转功能(由一个小游戏跳转到另一个小游戏)

    假设我们要实现的功能是从小游戏A跳转到小游戏B 对于小游戏A: (1)在platform.ts中添加代码如下: /** * 平台数据接口. * 由于每款游戏通常需要发布到多个平台上,所以提取出一个统一 ...

  9. cocos creator开发微信小游戏记录

    先用cocoscreator实现游戏逻辑 在cocoscreator项目里可以调用微信小游戏api 在cocos里面判断小游戏的运行环境 if (cc.sys.platform === cc.sys. ...

随机推荐

  1. 让Oracle 大小写敏感 表名 字段名 对像名

    一.解决方案 1.在表名.字段名.对象名上加上双引号,即可实现让oracle大小写区分. 2.但是这又引起了另一个问题:在数据库操作中,sql语句中相应的表名.字段名.对象名上一定要加双引号. 解决办 ...

  2. ITU-T Technical Paper: IP网络测量模型

    本文翻译自ITU-T的Technical Paper:<How to increase QoS/QoE of IP-based platform(s) to regionally agreed ...

  3. PS图层混合算法之四(亮光, 点光, 线性光, 实色混合)

    亮光模式: 根据绘图色通过增加或降低"对比度",加深或减淡颜色.如果绘图色比50%的灰亮,图像通过降低对比度被照亮,如果绘图色比50%的灰暗,图像通过增加对比度变暗. 线性光模式: ...

  4. 避免"Physics Space Locked"错误

    在一些cocos2d中使用物理引擎的代码中,往往会出现如下错误: Aborting due to Chipmunk error: You cannot manually reindex objects ...

  5. RPi Kernel Compilation

    Overview This page explains how to rebuild the kernel image for the RPi. There are two possible rout ...

  6. 单片机驱动AT24C02存储芯片

    AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗.AT24C02有一个8字节页写缓冲器.该器件通过IIC总 ...

  7. HFile

    HFile存储格式 HBase中的所有数据文件都存储在Hadoop HDFS文件系统上,主要包括两种文件类型: 1. HFile, HBase中KeyValue数据的存储格式,HFile是Hadoop ...

  8. 设置UIButton中的文字和图片,设置UILabel的文在显示不同颜色

    UIButton: UIEdgeInsets 在UIButton中有三个对EdgeInsets的设置:ContentEdgeInsets.titleEdgeInsets.imageEdgeInsets ...

  9. netsh自动配置网络

    工作需要经常在多个网络中切换,每次都要配置ip等,写个脚本一键完成配置: netsh interface ip set address "本地连接" static "ip ...

  10. C# 中的线程安全集合类

    C# 的集合类型中, 都有Synchronized静态方法, 和SyncRoot实例方法 对于ArrayList以及Hashtable 集合类来讲,当需要做到线程安全的时候,最好利用其自带的属性Syn ...