THREE.PointerLockControls不会锁定我的指针

时间:2018-09-09 08:17:13

标签: javascript three.js

Uncaught TypeError: THREE.PointerLockControls is not a constructor

无论出于何种原因,我都无法使用第一人称控件,因为这个原因,我真的迷失了。这真让我感到难过。

  const THREE = require('THREE');
  var FirstPersonControls = require('first-person-controls');

  const CANNON = require('cannon');
  var keyboard  = new THREEx.KeyboardState();
  var lights = [];
  var camSpeed = 1;
  var world, mass, body, body2, shape, shape2, timeStep=1/60,
     camera, scene, renderer, geometry, material, mesh, textureCube;
  initThree();
  initCannon();
  animate();
  function initCannon() {
      world = new CANNON.World();
      world.gravity.set(0,-9.8,0);
      world.broadphase = new CANNON.NaiveBroadphase();
      world.solver.iterations = 10;
      shape = new CANNON.Box(new CANNON.Vec3(1,1,1));
      shape2 = new CANNON.Box(new CANNON.Vec3(50,1,50));
      mass = 1;
      body = new CANNON.Body({
        mass: 1
      });
      body2 = new CANNON.Body({
        mass: 0
      });
      body.position.set(1,10,1);
      body.addShape(shape);
      body2.addShape(shape2);
      body.angularDamping = 0.5;
      world.addBody(body);
      world.addBody(body2);
  }
  function initThree() {
      scene = new THREE.Scene();
      camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );
      var controls = new THREE.FirstPersonControls(camera);
        controls.lookSpeed = 0.1;
        controls.movementSpeed = 10;

        var clock = new THREE.Clock(true);
      var prefix = ".png"
      var r = __dirname + "/skyboxes/mp_cliffside/";
            var urls = [
                r + "px" + prefix, r + "nx" + prefix,
                r + "py" + prefix, r + "ny" + prefix,
                r + "pz" + prefix, r + "nz" + prefix
            ];
            textureCube = new THREE.CubeTextureLoader().load( urls );
    var dottedAlphaMap = new THREE.TextureLoader().load( __dirname + "/textures/brickmap.png" );
    var dottedAlphaMap2 = new THREE.TextureLoader().load( __dirname + "/textures/stonemap-wet-texture.jpg" );


            scene.background = textureCube;
      lights[0] = new THREE.PointLight( '#ffffff', 3, 100 );
        lights[0].position.set( 0, 5, 0 );
        scene.add( lights[0] );
      scene.add( camera );
      renderer = new THREE.WebGLRenderer({ alpha:false });
      renderer.setSize( window.innerWidth, window.innerHeight );
      camera.position.y = 40;
      camera.rotation.x = -90 * Math.PI / 180;
      document.body.appendChild( renderer.domElement );


  }
  function animate() {
      requestAnimationFrame( animate );
      updatePhysics();
      render();
  }
  var controllee = camera;
  function updatePhysics() {
      // Step the physics world
      world.step(timeStep);
      // Copy coordinates from Cannon.js to Three.js
      lights[0].position.copy(camera.position)
  }
  function render() {
    requestAnimationFrame(render);

    controls.update(clock.getDelta());
    if(keyboard.pressed("F")){
        camera.fov += 0.1;
            camera.updateProjectionMatrix();
    }
    if(keyboard.pressed("G")){
        camera.fov -= 0.1;
            camera.updateProjectionMatrix();
    }
    if(keyboard.pressed("space")){
        controllee.translateY(camSpeed/10);
    }
    if(keyboard.pressed("shift")){
        controllee.translateY(-camSpeed/10);
    }
    if(keyboard.pressed("W")){
        controllee.translateZ(-camSpeed/10);
    }
    if(keyboard.pressed("S")){
        controllee.translateZ(camSpeed/10);
    }
    if(keyboard.pressed("A")){
        controllee.translateX(-camSpeed/10);
    }
    if(keyboard.pressed("D")){
        controllee.translateX(camSpeed/10);
    }
    if(keyboard.pressed("I")){
        controllee.rotateX(camSpeed/100);
    }
    if(keyboard.pressed("K")){
        controllee.rotateX(-camSpeed/100);
    }
    if(keyboard.pressed("J")){
        controllee.rotateY(camSpeed/100);
    }
    if(keyboard.pressed("L")){
        controllee.rotateY(-camSpeed/100);
    }
    if(keyboard.pressed("U")){
        controllee.rotateZ(camSpeed/100);
    }
    if(keyboard.pressed("O")){
        controllee.rotateZ(-camSpeed/100);
    }
      renderer.render( scene, camera );
  }

我正在使用从节点包管理器导入的three.js和cannon.js。

我正在尝试使控件像fps一样,但是类似的东西一直在困扰我!

感谢您的帮助,我唯一能想到的是它不包含在NPM的三个版本中,在这种情况下,我是SOL

更新:我已经更改了代码,以通过标签包含三个代码。 PointerLockControls也一样,但是现在的问题是我不知道如何锁定指针。

2 个答案:

答案 0 :(得分:1)

了解,您必须使用“ controls.lock()”有效地将鼠标锁定在屏幕上(您的指针将消失,您将能够像FPS游戏一样环顾四周)。

不幸的是,您不能从代码中锁定鼠标指针。而是需要与DOM ELEMENT的用户交互。

通过使用document.body,可以使用的最简单的Dom元素是“ body”。请参阅:

//add document.body to PointerLockControls constructor
let fpsControls = new PointerLockControls( camera ,  document.body );

//add event listener to your document.body
document.body.addEventListener( 'click', function () {
    //lock mouse on screen
    fpsControls.lock();
}, false );

注意1:无需在动画函数中调用fpsControls.update();

注2:确保您的身体部分位于画布的前部并覆盖整个屏幕,如有必要,在画布的CSS上设置z-index:-1(或在body的CSS中设置z-index:10) 。示例:

body{
  z-index: 10
  margin: 0;
  padding: 0;
  height: 100vh;
  width: 100vh;
  overflow: hidden;
}

这样,您可以单击屏幕上的任意位置以体验预期的行为。 ESC将使您解锁控制器

保持冷静和快乐编码

答案 1 :(得分:0)

  

但是现在的问题是我不知道如何锁定指针。

您可以按照以下example中的步骤进行操作:

  • 创建显示“点击播放”的初始屏幕
  • 为相应的DOM元素注册click事件监听器
  • 在监听器代码调用document.body.requestPointerLock()中,以异步方式向浏览器询问指针锁定