微信小遊戲開發之五:爲three.js添加物理引擎Physijs

一、前言

The primary goal in developing Physijs is to keep it as simple and user-friendly as possible. Physics engines can be daunting and difficult to set up, with so many options and configurations it is easy to feel overwhelmed. Physijs abstracts all of that extra logic out so you can focus on the rest of your project.
簡單的來說,physijs這個名字看起來拼寫錯誤的東西,是一套把ammo.js中的底層接口,抽象出來,針對three.js封裝好之後,便於使用的物理引擎。

二、GitHub地址

三、兼容經歷

1、物理引擎基於worker來進行模擬,而微信開發工具中worker卻有bug,無法創建,在最新版本中以修復。
2、Physijs中包含physi.js、ammo.js、physijs_worker.js,除了ammo這個基礎物理庫以外,另外兩個都有部分源碼需要修改,主要是對wx的適配。
3、worker文件需要放在worker目錄中,並在game.json中指明路徑,worker中需要引用到的其他代碼文件,必須一併放到worker目錄中。

四、代碼

使用physijs的區別主要在於將原本部分使用THREE的接口改變爲Physiji即可:
let THREE = require('./three/three')
import Physijs from './three/physi'

export default class game3d {
    constructor() {
        Physijs.scripts.worker = 'workers/request/physijs_worker.js';
        // 此處ammo.js需要直接在worker中進行綁定
        // Physijs.scripts.ammo = './ammo.js';

        // 場景
        this.scene = new Physijs.Scene();
        console.log(this.scene)
        // 透視攝像頭
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        // webGL渲染器
        // 同時指定canvas爲小遊戲暴露出來的canvas
        this.renderer = new THREE.WebGLRenderer({
            canvas: canvas,
            antialias: true
        });
        this.renderer.shadowMapEnabled = true;

        this.light = new THREE.AmbientLight(0xffffff);
        this.scene.add(this.light);
        this.start()
    }
    start() {
        // 在場景中添加霧的效果;樣式上使用和背景一樣的顏色
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        var geometry = new THREE.CubeGeometry(1, 1, 1);
        // 加載紋理貼圖
        var texture = new THREE.TextureLoader().load("images/metal.jpg");
        var material = new THREE.MeshBasicMaterial({ map: texture });
        this.ground = this.createGround()
        this.stage = this.createStage()
        this.scene.add(this.ground);
        this.scene.add(this.stage);
        // 設置camera的高度,若是低於當前場景的高度則屁也看不到
        this.camera.position.z = 15;
        this.camera.position.y = 10;
        this.box = new Physijs.BoxMesh(new THREE.CubeGeometry(1, 1, 1), material);
        this.box.position.y = 10
        this.scene.add(this.box);
        window.requestAnimationFrame(this.loop.bind(this), canvas);
    }
    createGround() {
        var geometry = new THREE.BoxGeometry(30, 1, 30);
        var texture = new THREE.TextureLoader().load("images/metal.jpg");
        var material = new THREE.MeshBasicMaterial({ map: texture });
        let cylinder = new Physijs.BoxMesh (geometry, material, 0);
        cylinder.position.y = 0
        cylinder.position.x = 0.5

        return cylinder
    }
    createStage() {
        var geometry = new THREE.CylinderGeometry(3, 1, 3);
        var texture = new THREE.TextureLoader().load("images/metal.jpg");
        var material = new THREE.MeshBasicMaterial({ map: texture });
        let cylinder = new Physijs.CylinderMesh(geometry, material);
        cylinder.position.y = 5
        cylinder.position.x = 0.5

        return cylinder
    }
    update() {
        this.stage.setAngularVelocity(new THREE.Vector3(0, 5, 0))
        // this.ground.setLinearVelocity(new THREE.Vector3(1, 1, 0))
        // 無法直接改變旋轉角度
        // this.box.rotation.z += 0.06;
    }
    loop() {
        this.update()
        this.scene.simulate(); // run physics
        this.renderer.render(this.scene, this.camera);
        window.requestAnimationFrame(this.loop.bind(this), canvas);
    }
}

Physi.js源碼修改部分

1、導出Physiji

let THREE = require('./three')
export default Physijs()
把window.Physijs = (function() {...})
改成function Physijs(){...}
2、修改worker適配wx

this._worker = wx.createWorker('workers/request/physijs_worker.js');
//...
//將this._worker.onmessage()改爲
this._worker.onMessage((data)=>{
    //...
})

Physiji_worker.js源碼修改部分

1、導入ammo.js

//將兩文件全部放入worker目錄中
require('./ammo.js')
//找到並將下面這行代碼註釋
//importScripts( params.ammo );

2、適配wx接口

// 將onmessage修改如下
worker.onMessage((res) => {
    //res參數進行匹配
    //...
})

worker配置和目錄結構




五、效果




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章