import * as RE from "rogue-engine"; import { Object3D, PerspectiveCamera, Vector3 } from "three"; const fwdDirection = new Vector3(0, 0, -1); const bwdDirection = new Vector3(0, 0, 1); const leftDirection = new Vector3(-1, 0, 0); const rightDirection = new Vector3(1, 0, 0); export default class FPSController extends RE.Component { @RE.props.num() rotSpeed: number = 1; @RE.props.num(-Math.PI/2, 0) minCameraRotY: number = -1.5708; @RE.props.num(0, Math.PI/2) maxCameraRotY: number = 1.5708; @RE.props.num() cameraHeight: number = 0.4; @RE.props.num() walkSpeed: number = 2; @RE.props.num() fwdSpeedMultiplier: number = 1.3; @RE.props.num() runSpeedMultiplier: number = 1.8; @RE.props.object3d() character: Object3D; camera: PerspectiveCamera; awake() { RE.Input.mouse.lock(); this.camera = new PerspectiveCamera(); RE.App.currentScene.add(this.camera); RE.App.activeCamera = this.camera.uuid; this.camera.position.copy(this.character.position); this.camera.position.y += this.cameraHeight; this.camera.rotation.copy(this.character.rotation); const appContainer = document.getElementById("rogue-app"); if (!appContainer) return; appContainer.onmousedown = (e) => { RE.Input.mouse.lock(); }; RE.Runtime.onStop(() => { if (!appContainer) return; appContainer.onmousedown = null; }); this.camera.rotation.order = "YXZ"; this.character.rotation.order = "YXZ"; this.camera.up.set(0, 1, 0); } update() { const deltaTime = RE.Runtime.deltaTime; if (RE.Input.mouse.isMoving && document.pointerLockElement) { const mouseDeltaX = RE.Input.mouse.movementX * this.rotSpeed * deltaTime; const mouseDeltaY = RE.Input.mouse.movementY * this.rotSpeed * deltaTime; this.character.rotation.set( this.character.rotation.x, this.character.rotation.y - mouseDeltaX, this.character.rotation.z ); this.camera.rotation.set( this.camera.rotation.x - mouseDeltaY, this.character.rotation.y, this.camera.rotation.z ); this.camera.rotation.x = Math.max( this.minCameraRotY, Math.min(this.maxCameraRotY, this.camera.rotation.x) ); } RE.Input.keyboard.getKeyPressed("Escape") && RE.Input.mouse.unlock(); let actualSpeed = this.walkSpeed; let onlyFwd = true; const movementVector = new Vector3(); if (RE.Input.keyboard.getKeyDown("Space")) { //jump logic here } if (RE.Input.keyboard.getKeyPressed("KeyW")) { movementVector.add(fwdDirection); } else if (RE.Input.keyboard.getKeyPressed("KeyS")) { movementVector.add(bwdDirection); onlyFwd = false; } if (RE.Input.keyboard.getKeyPressed("KeyA")) { movementVector.add(leftDirection); onlyFwd = false; } else if (RE.Input.keyboard.getKeyPressed("KeyD")) { movementVector.add(rightDirection); onlyFwd = false; } if (onlyFwd) { if (RE.Input.keyboard.getKeyPressed("ShiftLeft")) { actualSpeed *= this.runSpeedMultiplier; } else { actualSpeed *= this.fwdSpeedMultiplier; } } movementVector.normalize(); if (movementVector.length() > 0) { movementVector.copy( movementVector .transformDirection(this.character.matrix) .multiplyScalar(actualSpeed * deltaTime) ); this.character.position.x += movementVector.x; this.character.position.z += movementVector.z; } this.camera.position.set( this.character.position.x, this.character.position.y + this.cameraHeight, this.character.position.z ); } } RE.registerComponent(FPSController);