第一人称控件中的THREE.js A和D运动

时间:2018-09-09 02:41:46

标签: javascript three.js

我试图在THREE.js中从头开始制作第一人称的控件原型。我已经成功地使前后运动起作用了,但是我的左和右(a,d)运动却不能起作用。我尝试从视角添加和减去90度,然后找到它的正弦和余弦值。但它不起作用。

我当时想让玩家切线运动,但不认为那是正确的,也不知道该怎么做。

<!DOCTYPE html>
<html>
<head>
	<title>THREEJS</title>
	<style>
		body {
			margin: 0;
		}
	</style>
</head>
<body>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
	<script type="text/javascript">
		let width = innerWidth
		let height = innerHeight

		let scene = new THREE.Scene()
		let camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)

		let renderer = new THREE.WebGLRenderer({ antialias: true })
		renderer.setSize(width, height)
		document.body.appendChild(renderer.domElement)
		
		let cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), 
			new THREE.MeshLambertMaterial({ color: 0x00FF00, wireframe: false }))
		let plane = new THREE.Mesh(new THREE.PlaneGeometry(20, 20, 20, 10),
			new THREE.MeshLambertMaterial({ color: 0xFFFFFF, wireframe: false }))
		let light = new THREE.PointLight(0xFFFFFF, 1.5, 20)

		plane.rotation.set(-Math.PI / 2, 0, 0)
		cube.position.set(0, 1, 0)
		light.position.set(0, 10, 0)

		scene.add(cube)
		scene.add(plane)
		scene.add(light)

		addEventListener("resize", () => {
			width = innerWidth
			height = innerHeight
			renderer.setSize(width, height)
			camera.aspect = width / height
			camera.updateProjectionMatrix()
		})

		camera.position.set(0, 1, 0)

		renderer.domElement.onclick = () =>
			renderer.domElement.requestPointerLock()
		document.addEventListener('pointerlockchange', lockChangeAlert, false);
		document.addEventListener('mozpointerlockchange', lockChangeAlert, false);


		let player = new THREE.Object3D()
		player.position.set(0, 0, 0)

		player.add(camera)
		scene.add(player)


		function updatePosition(event) {
			camera.rotation.order = 'YZX'
			let { movementX, movementY } = event
			let rotateSpeed = 0.002
			player.rotation.y -= movementX * rotateSpeed
			camera.rotation.x -= movementY * rotateSpeed
			camera.rotation.x = Math.max(-Math.PI / 2, Math.min(camera.rotation.x, Math.PI / 2))
			camera.rotation.order = 'XYZ'
		}

		function lockChangeAlert() {
			if (document.pointerLockElement == renderer.domElement) {
				document.addEventListener("mousemove", updatePosition, false)
			} else {
				document.removeEventListener("mousemove", updatePosition, false)
			}
		}

		let keys = {}
		function keyDown(event) {
			keys[event.key] = true
		}
		function keyUp(event) {
			delete keys[event.key]
		}

		document.onkeydown = keyDown
		document.onkeyup = keyUp

		function update() {
			let moveSpeed = 0.05

			cube.rotation.x += 0.01
			cube.rotation.y += 0.01

			if(keys["w"]) {
				player.position.x -= Math.sin(player.rotation.y) * moveSpeed
				player.position.z -= Math.cos(player.rotation.y) * moveSpeed
			}
			if(keys["s"]) {
				player.position.x += Math.sin(player.rotation.y) * moveSpeed
				player.position.z += Math.cos(player.rotation.y) * moveSpeed
			}

			if(keys["d"]) {
				player.position.x += moveSpeed * Math.sin(player.rotation.y + Math.PI / 2)
				player.position.z += moveSpeed * Math.cos(player.rotation.y - Math.PI / 2)
			}
			if(keys["a"]) {
				player.position.x -= moveSpeed * Math.sin(player.rotation.y + Math.PI / 2)
				player.position.z -= moveSpeed * Math.cos(player.rotation.y - Math.PI / 2)
			}

		}

		function draw() {
			renderer.render(scene, camera)
		}

		function loop() {
			update()
			draw()

			requestAnimationFrame(loop)
		}

		loop()
    </script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

啮合一些后,我做到了,并使其正常工作

if(keys["d"]) {
    player.position.x += moveSpeed * Math.sin(rotation + Math.PI / 2)
    player.position.z += moveSpeed * Math.cos(rotation + Math.PI / 2)
}
if(keys["a"]) {
    player.position.x += moveSpeed * Math.sin(rotation - Math.PI / 2)
    player.position.z += moveSpeed * Math.cos(rotation - Math.PI / 2)
}