Reputation: 81
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
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
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:
click
event listener to the respective DOM element document.body.requestPointerLock()
in order to asynchronously ask the browser for the pointer lockUpvotes: 2