1. 程式人生 > >微信小遊戲開發之五:為three.js新增物理引擎Physijs

微信小遊戲開發之五:為three.js新增物理引擎Physijs

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配置和目錄結構



五、效果