【转】利用 three.js 开发微信小游戏的尝试
前言
这是一次利用 three.js
开发微信小游戏的尝试,并不能算作是教程,只能算是一篇笔记吧。
微信 WeChat 6.6.1 开始引入了微信小游戏,初期上线了一批质量相当不错的小游戏。我在查阅各处的文章时候,发现其中有几款是基于 three.js 开发的,目前火爆朋友圈的《跳一跳》就是其中之一。这引起了我的注意,想起几年前也做过不少 WebGL 的尝试,于是禁不住想要弄到微信小游戏平台上试试。
准备工作
另外补充一点:需要足够的耐心,微信开发者工具问题多多,编辑器也各种问题,我是使用 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
- 其中,
images
目录里面放置我们需要使用到的图片,在这个例子中,我放了粒子图片和 indienova Logo 图片在里面; - 将我们必然会用到的
three.js
(使用three.min.js
也可以,但是后面需要修改这个文件,所以建议使用没有 minified 的版本)放入js/libs
; - 如果有其它资源,比如音频文件什么的,也可以自建目录放进去;
- 然后需要修改一下配置文件,简单的说,只要修改
project.config.json
中的projectname
即可; - 保留
game.js
不变,这个是入口,会引入main.js
并执行; - 将
main.js
清空,我们的新代码会在这里完成。
我们还保留了两个 js 文件,libs
中的 symbol.js
和 weapp-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
,所以我们无需自己再进行创建,只需要取得的 canvas
的 context
就可以了,这里我们使用的不是 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-jsgithub.com
参考链接
这几天研究这部分内容的时候,遇到不少奇怪的问题,这部分内容又很难依靠 Google 和 StackOverflow 来解决,还好找到了交流的 QQ 群,以及群中成员的交流心得,才算完成了这次尝试。
- 参与的微信小游戏 QQ 群:117844722
- 参考的文章:在微信小游戏中使用 three.js 显示3D 图形
其它相关链接
请先阅读:微信小游戏官方文档
目前,Cocos、Egret、Laya 已经完成了自身引擎及其工具对小游戏的适配和支持,访问对应的官方文档可以更快地接入小游戏的开发
- Cocos:http://docs.cocos.com/creator/manual/zh/publish/publish-wechatgame.html
- Egret:http://developer.egret.com/cn/github/egret-docs/Engine2D/minigame/introduction/index.html
- Laya:https://ldc.layabox.com/doc/?nav=zh-as-3-4-5
您可能感兴趣的
原文链接:https://zhuanlan.zhihu.com/p/32648805
【转】利用 three.js 开发微信小游戏的尝试的更多相关文章
- 使用Laya引擎开发微信小游戏(上)
本文由云+社区发表 使用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏. 作者:马晓东,腾讯前端高级工程师. 微信小游戏的推出也快一年时间了,在IEG的游戏运营活动中,也出现 ...
- 用Vue.js开发微信小程序:开源框架mpvue解析
前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...
- 使用Laya引擎开发微信小游戏
在支持微信小游戏的游戏引擎中,Cocos,Egret,Laya都对小游戏的开发提供了很多强大的支持.前段时间正好抽空研究了一下这块的内容,现做一个总结,针对如何使用Laya引擎开发微信小游戏给大家做一 ...
- MPVUE - 使用vue.js开发微信小程序
MPVUE - 使用vue.js开发微信小程序 什么是mpvue? mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架.框架提供了完整的 Vue.js 开发体验,开发 ...
- 使用Laya引擎开发微信小游戏(下)
本文由云+社区发表 6. 动画 6.1 创建伞兵对象 在src目录下创建一个新目录role,用来存放游戏中角色. 在role里创建一个伞兵Soldier.ts对象文件. module role{ ex ...
- Egret白鹭开发微信小游戏排行榜功能
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 我的个人博客 最近事情特别多,今天终于实现了排行榜功能,记录下来大家一起学习学习. 一.调用默认排行榜 首先我们需要了解: 1.白鹭开 ...
- Egret白鹭开发微信小游戏分享功能
今天给大家分享一下微信分享转发功能,话不多说,直接干 方法一: 1.在egret中打开Platfrom.ts文件,添加代码如下(当然,你也可以直接复制粘贴) /** * 平台数据接口. * 由于每款游 ...
- Egret白鹭开发微信小游戏程序跳转功能(由一个小游戏跳转到另一个小游戏)
假设我们要实现的功能是从小游戏A跳转到小游戏B 对于小游戏A: (1)在platform.ts中添加代码如下: /** * 平台数据接口. * 由于每款游戏通常需要发布到多个平台上,所以提取出一个统一 ...
- cocos creator开发微信小游戏记录
先用cocoscreator实现游戏逻辑 在cocoscreator项目里可以调用微信小游戏api 在cocos里面判断小游戏的运行环境 if (cc.sys.platform === cc.sys. ...
随机推荐
- Python学习笔记 - 切片
#!/usr/bin/env python3 # -*- coding: utf-8 -*- def fact(n): if n == 1: return 1 return n * fact(n - ...
- 《java入门第一季》之面向对象匿名内部类面试题
面试题一: /* 按照要求,补齐代码 interface Inter { void show(); } class Outer { // ...
- Android中SQLiteOpenHelper类的onUpgrade方法浅谈
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int new Version) 这个方法在实现时需要重写. onUpg ...
- C语言生成32位和64位随机数算法
C语言生成32位和64位随机数算法 /** * randstd.h * * Standard definitions and types, Bob Jenkins * * 2015-01-19: re ...
- 如何搭建modem编译环境
[DESCRIPTION] (1)MT6577以及之前的chip平台(如MT6575,73等) 的modem编译环境和MTK的Feature Phone的编译环境一样,即Windows+RVCT (2 ...
- 程序员编程艺术:第三章续、Top K算法问题的实现
程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha. 致谢:微软100题实现组,狂想曲创作组. 时间:2011年05月08日 ...
- Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能
Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...
- OpenCV——素描
具体的算法原理可以参考: PS滤镜,素描算法 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_ ...
- ZooKeeper 权限管理
这其中一个显而易见的问题就是权限:如果我的数据被别人动了怎么办? 方案一:采用ZooKeeper支持的ACL digest方式,用户自己定义节点的权限 这种方案将zookeeper的acl和diges ...
- disable table 失败的处理
相信每一个维护hbase集群的运维人员一定碰到过disable失败,陷入无穷的"Region has been PENDING_CLOSE for too long..."状态,此 ...