THREE.JS FPS视角旋转异常:相机卡顿并反向旋转问题求助
THREE.js FPS视角旋转卡顿并反向旋转问题
在实现第一人称射击(FPS)视角旋转系统时,相机在特定旋转角度(通过console.log查看this.rotation.y约为1/-1)会出现短暂卡顿,随后反向旋转,现象异常怪异。
game.js代码
//import 3d import * as engine from './three/src/Three.js' //import GLTF Loader import {GLTFLoader} from './three/examples/jsm/loaders/GLTFLoader.js' import {OBJLoader} from './three/examples/jsm/loaders/OBJLoader.js' import {MTLLoader} from './three/examples/jsm/loaders/MTLLoader.js' //import Player import {Player} from './src/player.js' //make player const player = new Player(0.1) //Make pause variable var isPaused = false; //make camera const camera = new engine.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); //change camera position player.position.z = 3; //create scene const scene = new engine.Scene(); //put skyblue background scene.background = new engine.Color("skyblue") //create renderer const renderer = new engine.WebGLRenderer(); //set renderer size renderer.setSize(window.innerWidth, window.innerHeight); //set renderer animation renderer.setAnimationLoop(animate) //set renderer.domElement style and attributes renderer.domElement.style.width = "100%"; renderer.domElement.style.height = "100%"; renderer.domElement.className = "main"; renderer.domElement.id = "main" //light: const ambientLight = new engine.AmbientLight(0xFFFFFF); ambientLight.intensity = 4; scene.add( ambientLight ); //game logic: //camera: //ask for pointer lock renderer.domElement.addEventListener("click", () => { renderer.domElement.requestPointerLock(); }) //Rotate the camera when mouse moving renderer.domElement.addEventListener("mousemove", player.handleMouseMove) //Make something when pointer lock document.addEventListener("pointerlockchange", () => { if (document.pointerLockElement === renderer.domElement) { isPaused = false; } else { isPaused = true; } }) setInterval(() => { if (isPaused) { player.needToHandleMouseMove = false; player.needToHandleKeyboard = false; document.getElementById("pauseMenu").style.display = ""; } else { player.needToHandleMouseMove = true; player.needToHandleKeyboard = true; document.getElementById("pauseMenu").style.display = "none"; } }, 20) //Make paused in start isPaused = true; // END OF CAMERA //Movement: document.addEventListener("keydown", player.handleKeyDown) document.addEventListener("keyup", player.handleKeyUp) //END OF MOVEMENT //disable scrolling document.addEventListener('wheel', (event) => {event.preventDefault();}, {passive: false}); //append the game document.body.appendChild(renderer.domElement); //name all laoders const glftLoader = new GLTFLoader(); const objLoader = new OBJLoader(); const mtlLoader = new MTLLoader(); //load my testmap glftLoader.load("./res/TestMap.gltf", (glftScene) => { var obj = glftScene.scene.children[0]; obj.position.x = 0; obj.position.y = 0; obj.position.z = 0; scene.add(obj) }) function animate(time) { player.checkForMovement(); camera.rotation.x = player.rotation.x; camera.rotation.y = player.rotation.y; camera.rotation.z = player.rotation.z; camera.position.x = player.position.x; camera.position.y = player.position.y; camera.position.z = player.position.z; renderer.render(scene, camera); }; //HTML Logic: document.getElementById("play").addEventListener("click", () => {isPaused = !isPaused; renderer.domElement.requestPointerLock()}) document.getElementById("menuquit").addEventListener("click", () => {window.location.href = "../../menus/index/index.html"}) document.getElementById("osquit").addEventListener("click", () => {require("electron").ipcRenderer.sendSync("closed", "close")})
src/Player.js代码
import * as THREE from '../three/src/Three.js' class Player { constructor(moveSpeed, keys = { W: false, A: false, S: false, D: false, ' ': false, SHIFT: false }) { this.moveSpeed = moveSpeed; this.keys = keys; this.position = new THREE.Vector3(); this.rotation = new THREE.Quaternion(); this.needToHandleMouseMove = false; this.needToHandleKeyboard = false; // Bind event handlers to the instance this.handleKeyDown = this.handleKeyDown.bind(this); this.handleKeyUp = this.handleKeyUp.bind(this); this.handleMouseMove = this.handleMouseMove.bind(this); } // Handle Key Down. PUT IN document.addEventListener("keydown") handleKeyDown(event) { if (this.needToHandleKeyboard) { const key = event.key.toUpperCase(); console.log("Key: " + key) if (this.keys.hasOwnProperty(key)) { this.keys[key] = true; if (key === ' ') { event.preventDefault(); } } } } // Handle Key Up. PUT IN document.addEventListener("keyup") handleKeyUp(event) { if (this.needToHandleKeyboard) { const key = event.key.toUpperCase(); console.log("KeyUp: " + key) if (this.keys.hasOwnProperty(key)) { this.keys[key] = false; } } } // Handle Mouse move. PUT IN document.addEventListener("mousemove") handleMouseMove(event) { if (this.needToHandleMouseMove) { let movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; let movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; let quaternionY = new THREE.Quaternion(); quaternionY.setFromAxisAngle(new THREE.Vector3(0, 1, 0), -movementX * 0.002); this.rotation.multiply(quaternionY); /* let quaternionX = new THREE.Quaternion(); quaternionX.setFromAxisAngle(new THREE.Vector3(1, 0, 0), -movementY * 0.002); let newRotation = this.rotation.clone().multiply(quaternionX); let angle = new THREE.Euler().setFromQuaternion(newRotation, 'YXZ').x; if (angle > -Math.PI / 2 && angle < Math.PI / 2) { this.rotation.copy(newRotation); } */ } } // Move the player with keys. PUT THAT IN ANIMATION LOOP checkForMovement() { let moveSpeedX = this.moveSpeed * Math.sin(this.rotation.y); let moveSpeedZ = this.moveSpeed * Math.cos(this.rotation.y); if (this.keys.W) { this.position.x -= moveSpeedX; this.position.z -= moveSpeedZ; } if (this.keys.S) { this.position.x += moveSpeedX; this.position.z += moveSpeedZ; } if (this.keys.D) { this.position.x += moveSpeedZ; this.position.z -= moveSpeedX; } if (this.keys.A) { this.position.x -= moveSpeedZ; this.position.z += moveSpeedX; } if (this.keys[' ']) this.position.y += this.moveSpeed; if (this.keys.SHIFT) this.position.y -= this.moveSpeed; } } export { Player };
内容的提问来源于stack exchange,提问作者Paolog
相关产品推荐
相关产品推荐

