user10322453
user10322453

Reputation: 81

THREE.PointerLockControls doesn't lock my pointer

Uncaught TypeError: THREE.PointerLockControls is not a constructor

I can't use firstperson controls for whatever reason, I am really lost for reason with this one. It's got me really stumped.

  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 );
  }

I am using imported three.js and cannon.js, from node package manager.

I am trying to get the controls to be like an fps, but stuff like this keeps getting in my way!

Any help is appreciated, the only thing i can think of is that its not included in the NPM version of three, in which case, I'm SOL

Update: I have changed my code to include three via a tag. Same goes with the PointerLockControls, but now the problem is that I dont know how the heck to lock the pointer.

Upvotes: 1

Views: 2910

Answers (2)

sugaith
sugaith

Reputation: 964

UNDERSTAND that you have to use "controls.lock()" to effectively lock your mouse to the screen (your pointer will disappear and you will be able to look around like a FPS game).

Unfortunately, you CAN NOT lock the mouse pointer from code. Instead, a user interaction WITH A DOM ELEMENT is required.

The simplest Dom element you can use is the "body", by using document.body.. see:

//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 );

NOTE 1: no need to call fpsControls.update() in animation function;

NOTE 2: make sure your body section is IN FRONT of the canvas and covering the entire screen, setting z-index: -1 on the canvas' CSS if necessary (or setting z-index: 10, in body's CSS ). Example:

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

This way, you can click anywhere in the screen to experience the expected behavior. ESC will make you unlock the controller

Keep Calm and Happy Coding

Upvotes: 3

Mugen87
Mugen87

Reputation: 31026

but now the problem is that I don't know how the heck to lock the pointer.

You can do it like in the following example:

  • Create splash screen that says "Click to Play"
  • Register an click event listener to the respective DOM element
  • In the listener code call document.body.requestPointerLock() in order to asynchronously ask the browser for the pointer lock

Upvotes: 2

Related Questions