如何修复三js摄像机控件仅更新以启动视图

问题描述 投票:0回答:1

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>First Person Game</title> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> let scene, camera, renderer; let moveForward = false, moveBackward = false, moveLeft = false, moveRight = false; let velocity = new THREE.Vector3(); let direction = new THREE.Vector3(); let canJump = false; let prevTime = performance.now(); let cubes = [], cubeVelocities = []; let heldCube = null; const speed = 150.0; const jumpVelocity = 75.0; const gravity = 9.8 * 50.0; const pickUpDistance = 2.0; const originalCubeScale = 1; const heldCubeScale = 0.5; const friction = 0.1; // Friction coefficient let pitch = 0, yaw = 0; init(); animate(); function init() { // Scene and camera setup scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.y = 1.6; // Renderer setup renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Ground const groundGeometry = new THREE.PlaneGeometry(50, 50); const groundMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const ground = new THREE.Mesh(groundGeometry, groundMaterial); ground.rotation.x = -Math.PI / 2; scene.add(ground); // Tangible cubes const cubeGeometry = new THREE.BoxGeometry(1, 1, 1); const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff }); for (let i = 0; i < 3; i++) { const cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.position.set(Math.random() * 30 - 15, 1.6, Math.random() * 30 - 15); cubes.push(cube); cubeVelocities.push(new THREE.Vector3()); scene.add(cube); } // Event listeners for movement document.addEventListener('keydown', onKeyDown); document.addEventListener('keyup', onKeyUp); // Lock the mouse document.body.addEventListener('click', () => { document.body.requestPointerLock(); }); document.addEventListener('mousemove', onMouseMove); window.addEventListener('resize', onWindowResize); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function onKeyDown(event) { switch (event.code) { case 'KeyW': moveForward = true; break; case 'KeyS': moveBackward = true; break; case 'KeyA': moveLeft = true; break; case 'KeyD': moveRight = true; break; case 'Space': if (canJump) { velocity.y = jumpVelocity; canJump = false; } break; case 'KeyF': pickOrThrowCube(); break; } } function onKeyUp(event) { switch (event.code) { case 'KeyW': moveForward = false; break; case 'KeyS': moveBackward = false; break; case 'KeyA': moveLeft = false; break; case 'KeyD': moveRight = false; break; } } function onMouseMove(event) { if (document.pointerLockElement) { const sensitivity = 0.002; yaw -= event.movementX * sensitivity; pitch -= event.movementY * sensitivity; pitch = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, pitch)); camera.rotation.y = yaw; camera.rotation.x = pitch; camera.rotation.z = 0; // Prevent rolling sideways } } function pickOrThrowCube() { if (heldCube) { // Throw the held cube const throwVelocity = new THREE.Vector3(); camera.getWorldDirection(throwVelocity); throwVelocity.multiplyScalar(200); // Throw strength heldCube.position.add(throwVelocity.multiplyScalar(0.02)); cubeVelocities[cubes.indexOf(heldCube)].copy(throwVelocity); heldCube.scale.set(originalCubeScale, originalCubeScale, originalCubeScale); // Reset cube scale heldCube = null; } else { // Pick up a cube if close enough and looking at it const raycaster = new THREE.Raycaster(); raycaster.setFromCamera(new THREE.Vector2(0, 0), camera); const intersects = raycaster.intersectObjects(cubes); if (intersects.length > 0) { const intersect = intersects[0]; if (intersect.distance < pickUpDistance) { heldCube = intersect.object; cubeVelocities[cubes.indexOf(heldCube)].set(0, 0, 0); // Stop the cube's movement heldCube.scale.set(heldCubeScale, heldCubeScale, heldCubeScale); // Make the cube smaller heldCube.position.copy(camera.position).add(camera.getWorldDirection(new THREE.Vector3()).multiplyScalar(1.5)); } } } } function animate() { requestAnimationFrame(animate); // Update time const time = performance.now(); const delta = (time - prevTime) / 1000; // Movement logic direction.z = Number(moveForward) - Number(moveBackward); direction.x = Number(moveRight) - Number(moveLeft); direction.normalize(); velocity.x -= velocity.x * 10.0 * delta; velocity.z -= velocity.z * 10.0 * delta; velocity.y -= gravity * delta; if (moveForward || moveBackward || moveLeft || moveRight) { const frontDirection = new THREE.Vector3(); camera.getWorldDirection(frontDirection); const rightDirection = new THREE.Vector3(); rightDirection.crossVectors(camera.up, frontDirection).normalize(); frontDirection.multiplyScalar(direction.z * speed * delta); rightDirection.multiplyScalar(direction.x * speed * delta); velocity.add(frontDirection).add(rightDirection); } camera.position.addScaledVector(velocity, delta); // Collision detection with barriers camera.position.x = Math.max(-24, Math.min(24, camera.position.x)); camera.position.z = Math.max(-24, Math.min(24, camera.position.z)); if (camera.position.y < 1.6) { velocity.y = 0; camera.position.y = 1.6; canJump = true; } // Update held cube position if (heldCube) { heldCube.position.copy(camera.position).add(camera.getWorldDirection(new THREE.Vector3()).multiplyScalar(1.5)); } // Cube collision logic for (let i = 0; i < cubes.length; i++) { if (cubes[i] !== heldCube) { // Apply friction cubeVelocities[i].x *= (1 - friction); cubeVelocities[i].z *= (1 - friction); // Apply gravity to cubes cubeVelocities[i].y -= gravity * delta; cubes[i].position.addScaledVector(cubeVelocities[i], delta); // Cube collision with ground: stop bouncing if (cubes[i].position.y < 0.5) { cubes[i].position.y = 0.5; cubeVelocities[i].y = 0; // Stop upward velocity } // Simple cube interaction logic for pushing for (let j = 0; j < cubes.length; j++) { if (i !== j) { const distance = cubes[i].position.distanceTo(cubes[j].position); if (distance < 1.5) { // If cubes are close enough const collisionDirection = new THREE.Vector3().subVectors(cubes[i].position, cubes[j].position).normalize(); const relativeVelocity = new THREE.Vector3().subVectors(cubeVelocities[i], cubeVelocities[j]); if (relativeVelocity.dot(collisionDirection) < 0) { // Only push if moving toward each other const pushAmount = 0.02; // Adjust to control push force cubeVelocities[i].add(collisionDirection.clone().multiplyScalar(pushAmount)); cubeVelocities[j].sub(collisionDirection.clone().multiplyScalar(pushAmount)); } } } } } } renderer.render(scene, camera); prevTime = time; } </script> </body> </html>


    

你需要添加

javascript three.js camera webgl
1个回答
0
投票

在您的

init()
函数

季节: 旋转矩阵乘法顺序

您可以在此处查看闻名的信息:

Https://en.wikipedia.org/wiki/euler_angles#rotation_matrix

也要添加此信息: const axesHelper = new THREE.AxesHelper( 15 ) //axesHelper.renderOrder = 1; axesHelper.material.depthTest = false; scene.add( axesHelper )

中它将显示世界轴(并且将始终处于所有对象的顶部),我需要在chekek chek的同时,所以也许您将来也需要它


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.