Anonymous
PointerLockControls Threejs «null не является объектом (оценка 'instructions.addEventListener')»
Сообщение
Anonymous » 09 янв 2026, 02:56
Я пытаюсь интегрировать PointerLockControls в свой проект.
Я использую пример со страницы примеров THREEJS, и я по сути скопировал то же самое, но он по-прежнему выдает ошибки в консоли и не запускается. Я использую базовую структуру кода и импортирую три через модуль узла и экспресс-сервер.
это мой основной HTML-код:
Код: Выделить всё
-
body {
margin: 0;
overflow: hidden;
}
.blocker {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.instructions {
width: 100%;
height: 100%;
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
-webkit-box-align: center;
-moz-box-align: center;
box-align: center;
color: #ffffff;
text-align: center;
font-family: Arial, sans-serif;
font-size: 14px;
line-height: 24px;
cursor: pointer;
}
Click to play
Move: WASD
Jump: SPACE
Look: MOUSE
а вот мой файл client.js:
Код: Выделить всё
//---------- Imports
import * as THREE from '/build/three.module.js';
//import {OrbitControls} from '/jsm/controls/OrbitControls.js';
import {PointerLockControls} from '/jsm/controls/PointerLockControls.js';
import Stats from '/jsm/libs/stats.module.js';
//---------- Setup
let camera, scene, renderer, controls;
const objects = [];
let raycaster;
let moveForward = false;
let moveBackward = false;
let moveLeft = false;
let moveRight = false;
let canJump = false;
let prevTime = performance.now();
const velocity = new THREE.Vector3();
const direction = new THREE.Vector3();
const vertex = new THREE.Vector3();
const color = new THREE.Color();
init();
animate();
//---------- Controls
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 10;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
scene.fog = new THREE.Fog( 0xffffff, 0, 750 );
const light = new THREE.HemisphereLight( 0xeeeeff, 0x777788, 0.75 );
light.position.set( 0.5, 1, 0.75 );
scene.add( light );
controls = new PointerLockControls( camera, document.body );
const blocker = document.getElementById( 'blocker' );
const instructions = document.getElementById( 'instructions' );
instructions.addEventListener( 'click', function () {
controls.lock();
} );
controls.addEventListener( 'lock', function () {
instructions.style.display = 'none';
blocker.style.display = 'none';
} );
controls.addEventListener( 'unlock', function () {
blocker.style.display = 'block';
instructions.style.display = '';
} );
scene.add( controls.getObject() );
const onKeyDown = function ( event ) {
switch ( event.code ) {
case 'ArrowUp':
case 'KeyW':
moveForward = true;
break;
case 'ArrowLeft':
case 'KeyA':
moveLeft = true;
break;
case 'ArrowDown':
case 'KeyS':
moveBackward = true;
break;
case 'ArrowRight':
case 'KeyD':
moveRight = true;
break;
case 'Space':
if ( canJump === true ) velocity.y += 350;
canJump = false;
break;
}
};
const onKeyUp = function ( event ) {
switch ( event.code ) {
case 'ArrowUp':
case 'KeyW':
moveForward = false;
break;
case 'ArrowLeft':
case 'KeyA':
moveLeft = false;
break;
case 'ArrowDown':
case 'KeyS':
moveBackward = false;
break;
case 'ArrowRight':
case 'KeyD':
moveRight = false;
break;
}
};
document.addEventListener( 'keydown', onKeyDown );
document.addEventListener( 'keyup', onKeyUp );
raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 );
// floor
let floorGeometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
floorGeometry.rotateX( - Math.PI / 2 );
// vertex displacement
let position = floorGeometry.attributes.position;
for ( let i = 0, l = position.count; i < l; i ++ ) {
vertex.fromBufferAttribute( position, i );
vertex.x += Math.random() * 20 - 10;
vertex.y += Math.random() * 2;
vertex.z += Math.random() * 20 - 10;
position.setXYZ( i, vertex.x, vertex.y, vertex.z );
}
floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices
position = floorGeometry.attributes.position;
const colorsFloor = [];
for ( let i = 0, l = position.count; i < l; i ++ ) {
color.setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
colorsFloor.push( color.r, color.g, color.b );
}
floorGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsFloor, 3 ) );
const floorMaterial = new THREE.MeshBasicMaterial( { vertexColors: true } );
const floor = new THREE.Mesh( floorGeometry, floorMaterial );
scene.add( floor );
// objects
const boxGeometry = new THREE.BoxGeometry( 20, 20, 20 ).toNonIndexed();
position = boxGeometry.attributes.position;
const colorsBox = [];
for ( let i = 0, l = position.count; i < l; i ++ ) {
color.setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
colorsBox.push( color.r, color.g, color.b );
}
boxGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsBox, 3 ) );
for ( let i = 0; i < 500; i ++ ) {
const boxMaterial = new THREE.MeshPhongMaterial( { specular: 0xffffff, flatShading: true, vertexColors: true } );
boxMaterial.color.setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
const box = new THREE.Mesh( boxGeometry, boxMaterial );
box.position.x = Math.floor( Math.random() * 20 - 10 ) * 20;
box.position.y = Math.floor( Math.random() * 20 ) * 20 + 10;
box.position.z = Math.floor( Math.random() * 20 - 10 ) * 20;
scene.add( box );
objects.push( box );
}
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
const time = performance.now();
if ( controls.isLocked === true ) {
raycaster.ray.origin.copy( controls.getObject().position );
raycaster.ray.origin.y -= 10;
const intersections = raycaster.intersectObjects( objects );
const onObject = intersections.length > 0;
const delta = ( time - prevTime ) / 1000;
velocity.x -= velocity.x * 10.0 * delta;
velocity.z -= velocity.z * 10.0 * delta;
velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass
direction.z = Number( moveForward ) - Number( moveBackward );
direction.x = Number( moveRight ) - Number( moveLeft );
direction.normalize(); // this ensures consistent movements in all directions
if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * delta;
if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * delta;
if ( onObject === true ) {
velocity.y = Math.max( 0, velocity.y );
canJump = true;
}
controls.moveRight( - velocity.x * delta );
controls.moveForward( - velocity.z * delta );
controls.getObject().position.y += ( velocity.y * delta ); // new behavior
if ( controls.getObject().position.y < 10 ) {
velocity.y = 0;
controls.getObject().position.y = 10;
canJump = true;
}
}
prevTime = time;
renderer.render( scene, camera );
}
вот мой app.js с базовой настройкой сервера выражений
Код: Выделить всё
const express = require('express')
const app = express()
const path = require('path')
app.use(express.static(__dirname + '/public'))
app.use('/build', express.static(path.join(__dirname, 'node_modules/three/build')));
app.use('/jsm/', express.static(path.join(__dirname, 'node_modules/three/examples/jsm')));
app.listen(3000, () =>
console.log('Visit http://127.0.0.1:3000')
);
и вот ошибка консоли, с которой я столкнулся:
Код: Выделить всё
[Error] TypeError: null is not an object (evaluating 'instructions.addEventListener')
init (client.js:61)
Modulcode (client.js:33)
evaluate
moduleEvaluation
(anonyme Funktion)
promiseReactionJob
Я, вероятно, совершаю базовую ошибку, но до сих пор не могу ее решить.
Я также боролся (хотя и выиграл битву), чтобы понять, как интегрировать Threejs через модуль es6, так что, возможно, ошибка где-то здесь. При необходимости я буду рад предоставить дополнительную информацию о структуре моего документа.
Большое спасибо.
Дэвид
Подробнее здесь:
https://stackoverflow.com/questions/666 ... ctions-add
1767916597
Anonymous
Я пытаюсь интегрировать PointerLockControls в свой проект. Я использую пример со страницы примеров THREEJS, и я по сути скопировал то же самое, но он по-прежнему выдает ошибки в консоли и не запускается. Я использую базовую структуру кода и импортирую три через модуль узла и экспресс-сервер. это мой основной HTML-код: [code] - body { margin: 0; overflow: hidden; } .blocker { position: absolute; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); } .instructions { width: 100%; height: 100%; display: -webkit-box; display: -moz-box; display: box; -webkit-box-orient: horizontal; -moz-box-orient: horizontal; box-orient: horizontal; -webkit-box-pack: center; -moz-box-pack: center; box-pack: center; -webkit-box-align: center; -moz-box-align: center; box-align: center; color: #ffffff; text-align: center; font-family: Arial, sans-serif; font-size: 14px; line-height: 24px; cursor: pointer; } Click to play Move: WASD Jump: SPACE Look: MOUSE [/code] а вот мой файл client.js: [code]//---------- Imports import * as THREE from '/build/three.module.js'; //import {OrbitControls} from '/jsm/controls/OrbitControls.js'; import {PointerLockControls} from '/jsm/controls/PointerLockControls.js'; import Stats from '/jsm/libs/stats.module.js'; //---------- Setup let camera, scene, renderer, controls; const objects = []; let raycaster; let moveForward = false; let moveBackward = false; let moveLeft = false; let moveRight = false; let canJump = false; let prevTime = performance.now(); const velocity = new THREE.Vector3(); const direction = new THREE.Vector3(); const vertex = new THREE.Vector3(); const color = new THREE.Color(); init(); animate(); //---------- Controls function init() { camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.y = 10; scene = new THREE.Scene(); scene.background = new THREE.Color( 0xffffff ); scene.fog = new THREE.Fog( 0xffffff, 0, 750 ); const light = new THREE.HemisphereLight( 0xeeeeff, 0x777788, 0.75 ); light.position.set( 0.5, 1, 0.75 ); scene.add( light ); controls = new PointerLockControls( camera, document.body ); const blocker = document.getElementById( 'blocker' ); const instructions = document.getElementById( 'instructions' ); instructions.addEventListener( 'click', function () { controls.lock(); } ); controls.addEventListener( 'lock', function () { instructions.style.display = 'none'; blocker.style.display = 'none'; } ); controls.addEventListener( 'unlock', function () { blocker.style.display = 'block'; instructions.style.display = ''; } ); scene.add( controls.getObject() ); const onKeyDown = function ( event ) { switch ( event.code ) { case 'ArrowUp': case 'KeyW': moveForward = true; break; case 'ArrowLeft': case 'KeyA': moveLeft = true; break; case 'ArrowDown': case 'KeyS': moveBackward = true; break; case 'ArrowRight': case 'KeyD': moveRight = true; break; case 'Space': if ( canJump === true ) velocity.y += 350; canJump = false; break; } }; const onKeyUp = function ( event ) { switch ( event.code ) { case 'ArrowUp': case 'KeyW': moveForward = false; break; case 'ArrowLeft': case 'KeyA': moveLeft = false; break; case 'ArrowDown': case 'KeyS': moveBackward = false; break; case 'ArrowRight': case 'KeyD': moveRight = false; break; } }; document.addEventListener( 'keydown', onKeyDown ); document.addEventListener( 'keyup', onKeyUp ); raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 ); // floor let floorGeometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 ); floorGeometry.rotateX( - Math.PI / 2 ); // vertex displacement let position = floorGeometry.attributes.position; for ( let i = 0, l = position.count; i < l; i ++ ) { vertex.fromBufferAttribute( position, i ); vertex.x += Math.random() * 20 - 10; vertex.y += Math.random() * 2; vertex.z += Math.random() * 20 - 10; position.setXYZ( i, vertex.x, vertex.y, vertex.z ); } floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices position = floorGeometry.attributes.position; const colorsFloor = []; for ( let i = 0, l = position.count; i < l; i ++ ) { color.setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); colorsFloor.push( color.r, color.g, color.b ); } floorGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsFloor, 3 ) ); const floorMaterial = new THREE.MeshBasicMaterial( { vertexColors: true } ); const floor = new THREE.Mesh( floorGeometry, floorMaterial ); scene.add( floor ); // objects const boxGeometry = new THREE.BoxGeometry( 20, 20, 20 ).toNonIndexed(); position = boxGeometry.attributes.position; const colorsBox = []; for ( let i = 0, l = position.count; i < l; i ++ ) { color.setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); colorsBox.push( color.r, color.g, color.b ); } boxGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsBox, 3 ) ); for ( let i = 0; i < 500; i ++ ) { const boxMaterial = new THREE.MeshPhongMaterial( { specular: 0xffffff, flatShading: true, vertexColors: true } ); boxMaterial.color.setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); const box = new THREE.Mesh( boxGeometry, boxMaterial ); box.position.x = Math.floor( Math.random() * 20 - 10 ) * 20; box.position.y = Math.floor( Math.random() * 20 ) * 20 + 10; box.position.z = Math.floor( Math.random() * 20 - 10 ) * 20; scene.add( box ); objects.push( box ); } // renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // window.addEventListener( 'resize', onWindowResize ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { requestAnimationFrame( animate ); const time = performance.now(); if ( controls.isLocked === true ) { raycaster.ray.origin.copy( controls.getObject().position ); raycaster.ray.origin.y -= 10; const intersections = raycaster.intersectObjects( objects ); const onObject = intersections.length > 0; const delta = ( time - prevTime ) / 1000; velocity.x -= velocity.x * 10.0 * delta; velocity.z -= velocity.z * 10.0 * delta; velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass direction.z = Number( moveForward ) - Number( moveBackward ); direction.x = Number( moveRight ) - Number( moveLeft ); direction.normalize(); // this ensures consistent movements in all directions if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * delta; if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * delta; if ( onObject === true ) { velocity.y = Math.max( 0, velocity.y ); canJump = true; } controls.moveRight( - velocity.x * delta ); controls.moveForward( - velocity.z * delta ); controls.getObject().position.y += ( velocity.y * delta ); // new behavior if ( controls.getObject().position.y < 10 ) { velocity.y = 0; controls.getObject().position.y = 10; canJump = true; } } prevTime = time; renderer.render( scene, camera ); } [/code] вот мой app.js с базовой настройкой сервера выражений [code]const express = require('express') const app = express() const path = require('path') app.use(express.static(__dirname + '/public')) app.use('/build', express.static(path.join(__dirname, 'node_modules/three/build'))); app.use('/jsm/', express.static(path.join(__dirname, 'node_modules/three/examples/jsm'))); app.listen(3000, () => console.log('Visit http://127.0.0.1:3000') ); [/code] и вот ошибка консоли, с которой я столкнулся: [code][Error] TypeError: null is not an object (evaluating 'instructions.addEventListener') init (client.js:61) Modulcode (client.js:33) evaluate moduleEvaluation (anonyme Funktion) promiseReactionJob [/code] Я, вероятно, совершаю базовую ошибку, но до сих пор не могу ее решить. Я также боролся (хотя и выиграл битву), чтобы понять, как интегрировать Threejs через модуль es6, так что, возможно, ошибка где-то здесь. При необходимости я буду рад предоставить дополнительную информацию о структуре моего документа. Большое спасибо. Дэвид Подробнее здесь: [url]https://stackoverflow.com/questions/66637686/pointerlockcontrols-threejs-null-is-not-an-object-evaluating-instructions-add[/url]