Physijs和setLinearVelocity:移动对象

时间:2015-02-01 04:43:14

标签: javascript three.js physijs

2-09-2015 - 更新:对于遇到与我相同问题的任何人,下面的代码与setLinearVelocity()一起使用。带有固定代码的原始问题可在下面找到......

我创建了一个由Physijs.BoxMesh组成的玩家对象。玩家拥有第一人称视野(现在是第三人称,因此我可以在排除故障时看到网格物体)并可以旋转摄像机视图并将玩家向不同方向移动。旋转效果很好,但我不能让网格移动。我正在使用setLinearVelocity()进行移动。

使用console.log(... getLinearVelocity)后,我可以看到速度正在正确更新。我做错了什么?

Player.js

    function Player() {
    this.bodyMesh = new Physijs.BoxMesh(
        new THREE.BoxGeometry(25, 25, 25),
        new Physijs.createMaterial(new THREE.MeshLambertMaterial({ color: 0xff0000 }), 1, .1),
        1
    );
    this.camera;

    this.bodyMesh.rotation.order = 'YXZ';
    this._aggregateRotation = new THREE.Vector3();

    // Public properties
    this.fly = false;
    this.cameraHeight = 40;
    this.maxHealth = 100;
    this.constrainVerticalLook = true;
    this.health = this.maxHealth;
    this.inverseLook = new THREE.Vector3(-1, -1, -1);
    this.mouseSensitivity = new THREE.Vector3(0.25, 0.25, 0.25);
    this.velocity = new THREE.Vector3();
    this.moveDirection = {
        FORWARD: false,
        BACKWARD: false,
        LEFT: false,
        RIGHT: false    
    };
}

Player.prototype.constructor = Player;

Player.SPEED = 5;
Player.RADIUS = 20;

Player.prototype.update = (function() {

    return function(delta) {
        // Compute look vector
        var r = this._aggregateRotation
                    .multiply(this.inverseLook)
                    .multiply(this.mouseSensitivity)
                    .multiplyScalar(delta)
                    .add(this.camera.rotation);
        if(this.constrainVerticalLook) {
            r.x = Math.max(Math.PI * -0.5, Math.min(Math.PI * 0.5, r.x));   
        }
        if(!this.fly) {
            this.bodyMesh.rotation.x = 0;   
        }

        // Thrust
        if(this.moveDirection.FORWARD) {
            this.velocity.z -= Player.SPEED;
        }
        if(this.moveDirection.LEFT) {
            this.velocity.x -= Player.SPEED;
        }
        if(this.moveDirection.BACKWARD) {
            this.velocity.z += Player.SPEED;
        }
        if(this.moveDirection.RIGHT) {
            this.velocity.x += Player.SPEED;
        }
        this.bodyMesh.setLinearVelocity(this.velocity);

        // Look
        this.camera.rotation.set(r.x, r.y, r.z);
        this._aggregateRotation.set(0,0,0);
    };
})();

// Parameters are in pixel distances representing mouse movement
Player.prototype.rotate = function(x, y, z) {
    this._aggregateRotation.x += x;
    this._aggregateRotation.y += y;
    this._aggregateRotation.z += z;
};

Main.js

    Physijs.scripts.worker = 'js/lib/physijs_worker.js';
Physijs.scripts.ammo = 'ammo.js';

// GLOBALS ==============================================

var renderer, scene, camera, light, clock;

var player, enemy;

var plane, ball;
var ARATE = 2000; // delay for setInterval(function(){}, delay)
var WIDTH = window.innerWidth,
    HEIGHT = window.innerHeight,
    VIEW_ANGLE = 45,
    ASPECT = WIDTH / HEIGHT,
    NEAR = 1,
    FAR = 10000;
var INV_MAX_FPS = 1 / 100;
var frameDelta = 0;


// ANIMATION LOOP==============================================================

function animate() {
    draw();
    requestAnimationFrame(animate);
}

// SETUP ================================================

function setup() {
    setupThreeJS();
    setupWorld();
    requestAnimationFrame(animate);
    scene.simulate();
}

function setupThreeJS() {
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMapEnabled = true;
    renderer.shadowMapSoft = true;
    renderer.shadowMapType = THREE.PCFShadowMap;
    renderer.shadowMapAutoUpdate = true;
    $("#viewport").append(renderer.domElement);

    renderStats = new Stats();
    renderStats.domElement.style.position = 'absolute';
    renderStats.domElement.style.top = '0px';
    renderStats.domElement.style.zIndex = 100;
    $('#viewport').append(renderStats.domElement);

    scene = new Physijs.Scene();
    scene.setGravity(new THREE.Vector3(0, -30, 0));
    scene.addEventListener('update', function() {
        frameDelta += clock.getDelta();
        while(frameDelta >= INV_MAX_FPS) {
            update(INV_MAX_FPS);
            frameDelta -= INV_MAX_FPS;  
        }
        scene.simulate();
    });

    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    //camera.position.set(60, 40, 120);
    //camera.lookAt(scene.position);
    //scene.add(camera);

    clock = new THREE.Clock();

    light = new THREE.DirectionalLight(0xffffff);
    light.position.set(0, 100, 60);
    light.castShadow = true;
    light.shadowCameraLeft = -60;
    light.shadowCameraTop = -60;
    light.shadowCameraRight = 60;
    light.shadowCameraBottom = 60;
    light.shadowCameraNear = 1;
    light.shadowCameraFar = 1000;
    light.shadowBias = -.0001
    light.shadowMapWidth = light.shadowMapHeight = 1024;
    light.shadowDarkness = .7;

    scene.add(light);
}

function setupWorld() {
    plane = new Physijs.BoxMesh(
        new THREE.BoxGeometry(1000, 1000, 5, 50, 50),
        new Physijs.createMaterial(new THREE.MeshLambertMaterial({ color: 0xeeeeee }), .4, .8),
        0
    );

    plane.rotation.x = -Math.PI / 2;
    plane.receiveShadow = true;

    scene.add(plane);

    player = new Player();
    player.camera = camera;
    player.camera.position.y = 30;
    player.camera.position.z = 100;
    player.bodyMesh.add(player.camera);
    player.bodyMesh.position.y = 15;
    scene.add(player.bodyMesh);
}

// DRAW =======================================================================

function draw() {
    renderer.render(scene, camera); 
}

// UPDATE =====================================================================

function update(delta) {
    player.update(delta);
}

// INPUT ======================================================================

document.addEventListener('mousemove', function(event) {
    player.rotate(event.movementY, event.movementX, 0);
}, false);

document.addEventListener('keydown', function(event) {
    // Allow CTRL+L, CTRL+T, CTRL+W, and F5 for sanity
    if (!event.ctrlKey || !(event.keyCode == 76 || event.keyCode == 84 || event.keyCode == 87)) {
        if (event.keyCode != 116 && event.keyCode != 123) {
            event.preventDefault();
        }
    }
    switch (event.keyCode) {
        case 38: // up
        case 87: // w
            player.moveDirection.FORWARD = true;
            break;
        case 37: // left
        case 65: // a
            player.moveDirection.LEFT = true;
            break;
        case 40: // down
        case 83: // s
            player.moveDirection.BACKWARD = true;
            break;
        case 39: // right
        case 68: // d
            player.moveDirection.RIGHT = true;
            break;
        case 32: // space
            //player.jump();
            break;
    }
}, false);

document.addEventListener('keyup', function(event) {
    switch (event.keyCode) {
        case 38: // up
        case 87: // w
            player.moveDirection.FORWARD = false;
            break;
        case 37: // left
        case 65: // a
            player.moveDirection.LEFT = false;
            break;
        case 40: // down
        case 83: // s
            player.moveDirection.BACKWARD = false;
            break;
        case 39: // right
        case 68: // d
            player.moveDirection.RIGHT = false;
            break;
        case 32: // space
            break;
    }
}, false);

// RUN ===============================================

$(document).ready(function() {
    setup();
});

1 个答案:

答案 0 :(得分:0)

编辑刚刚尝试使用setLinearVelocity(),它可以使用上面的更新代码。