随着软硬件的发展,在PC和移动端浏览器上进行web 3D开发的条件已经基本成熟了,出现了不少js 3D库,Threejs是js 3D库中的佼佼者。国内也有企业开始做一些应用尝试,某宝2016年双11就用ThreeJS做了一个比较酷炫的3D宣传页面刷爆了朋友圈。
如今各种平台的小游戏也是五花八门,我们可以使用threeJS来做一个3D的小游戏,各种平台的小游戏不过是如出一辙,所以我就用微信小游戏为平台来示范如何在小游戏中引入threeJS引擎
一个网页浏览器
微信开发者工具
NodeJS、npm、cnpm
threeJS
官网对Threejs的介绍非常简单:“Javascript 3D library”。openGL是一个跨平台3D/2D的绘图标准,WebGL则是openGL在浏览器上的一个实现。web前端开发人员可以直接用WebGL接口进行编程,但WebGL只是非常基础的绘图API,需要编程人员有很多的数学知识、绘图知识才能完成3D编程任务,而且代码量巨大。Threejs对WebGL进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知识的情况下,也能够轻松进行web 3D开发,降低了门槛,同时大大提升了效率。
百度nodejs既可以搜索到nodejs中文网。进入下载可以下载对应版本进行安装
安装完成可在命令行检查是否安装完成
删除一些没用的文件(官方的游戏代码)写的非常精致,也可保留学习
留下小游戏框架文件和重要文件weapp-adapter.js
npm install --save three
输入npm install --save three
并会车,你会发现,并安装不了
于是我们要使用cnpm!
打开百度搜索cnpm
如图为cnpm官网
找到cnpm的安装命令:npm install -g cnpm --registry=https://registry.npm.taobao.org
在终端中执行npm install -g cnpm --registry=https://registry.npm.taobao.org
如图安装完成
cnpm install --save three
安装完成会发现小游戏中多了个目录,但好像并没有东西,其实这在编辑器里是隐藏的在文件夹中才看得见
使用npm模块
构建npm模块
打开game.js,输入如下代码
import './js/libs/weapp-adapter'
import './js/libs/symbol'
let THREE = require('three'); // 引入ThreeJS
继续在game.js中输入如下代码
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth * 0.75, window.innerHeight * 0.75);
document.body.appendChild(renderer.domElement);
let geometry = new THREE.BoxGeometry(1, 1, 1);
let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
let cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 10;
let R = 5;
let rotation = 0;
function update() {
requestAnimationFrame(update);
rotation += 1;
let _x = Math.sin(rotation / 180) * R;
let _z = Math.cos(rotation / 180) * R;
cube.position.x = _x;
cube.position.z = _z;
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
update();
这段代码运行后会让我们看见一个方块在旋转并做圆周运动
但是小游戏是一个不同于浏览器的 JavaScript 运行环境,没有 BOM 和 DOM API。然而,基本上所有基于 HTML5 的游戏引擎都是依赖浏览器提供的 BOM 和 DOM API 的。所以如果要在小游戏中使用引擎,需要对引擎进行改造。
之前保留的weapp-adapter.js是微信官方帮我们实现的BOM 和 DOM 的桥
我们已经引入他来为ThreeJS适配
但是如图所示,显然threeJS里使用了document.createElementNS
方法
let element =
document.createElementNS(namespaceURI, qualifiedName[, options]);
指定与元素相关联的命名空间URI的字符串。创建的元素的namespaceURI属性使用namespaceURI的值进行初始化。 参见有效的命名空间URL。
指定要创建的元素的类型的字符串。 创建的元素的nodeName属性使用qualifiedName的值进行初始化。
一个可选的包含单个属性的ElementCreationOptions对象,其值是预先使用customElements.define()定义的自定义元素的标签名称。为了向后兼容自定义元素规范的早期版本,一些浏览器允许您在此使用字符串替代对象,其中字符串的值是自定义元素的标签名称。有关如何使用此参数的详情,请参阅原生HTML元素。
新元素将被赋予一个属性,其值是自定义元素的标签名称。 自定义元素是实验中的功能,目前仅在某些浏览器中可用。
http://www.w3.org/1999/xhtml指定整个文档所使用的主要命名空间。不过即使你的文档没有使用此属性,W3C 的验证器也不会报错。因为 http://www.w3.org/1999/xhtml是一个固定值,所以,即使你没有包含它,此值也会被添加到 标签中。
并查阅ThreeJS源码
发现使用改方法的地方共有四处
均是指向了一个命名空间,在这里并没有任何用处,所以可以将四处
document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
都按照这种方式进行修改
document.createElement('canvas');
那是因为我们使用的document.body.appendChild(renderer.domElement);
方法是浏览器拥有的,在小程序里并没有
于是我们应该在创建WebGLRenderer时指定绘制的canvas
将
let renderer = new THREE.WebGLRenderer();
改成
let renderer = new THREE.WebGLRenderer({ context: canvas.getContext('webgl')});
刷新就出现了我们想要的样子
同时window.innerWidth
和window.innerHeight
也建议修改成canvas.width
和canvas.height