From 14772a039cd483a16c88f5b38cde98b8b5acd29a Mon Sep 17 00:00:00 2001 From: goynov Date: Sun, 30 Nov 2025 09:42:29 +0200 Subject: [PATCH] advanced character controls + zoom/fov --- .../InteractiveObjects/ImageObject.js | 1 - src/lib/Dashboard.js | 13 ++-- src/lib/GameEngine.js | 10 ++- src/lib/Hero.js | 67 +++++++++++++------ src/lib/PointerControls.js | 1 - 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/components/InteractiveObjects/ImageObject.js b/src/components/InteractiveObjects/ImageObject.js index 8665d49..8a781ea 100644 --- a/src/components/InteractiveObjects/ImageObject.js +++ b/src/components/InteractiveObjects/ImageObject.js @@ -1,5 +1,4 @@ import { TextureLoader, MeshStandardMaterial, MeshBasicMaterial, PlaneGeometry, Mesh, DoubleSide, Vector3 } from "three"; -import { assignParams } from "@/lib/MeshUtils"; class ImageObject { constructor(engine, obj) { diff --git a/src/lib/Dashboard.js b/src/lib/Dashboard.js index b3ff476..2f3ec67 100644 --- a/src/lib/Dashboard.js +++ b/src/lib/Dashboard.js @@ -61,7 +61,7 @@ class DashBoard { ); const loadingProgress = new ProgressBar(engine); loadingProgress.object.scale.set(engine.aspect*0.8, 0.05, 0.05) - loadingProgress.object.position.set(-engine.aspect/2 + engine.aspect*0.1, 0, 0.1) + loadingProgress.object.position.set(-engine.aspect/2 + engine.aspect*0.1, 0, 0) loadingPlane.add(loadingProgress.object); dash.add(loadingPlane); @@ -74,7 +74,7 @@ class DashBoard { transparent:true }) ); - hudPlane.position.z = -0.22; + hudPlane.position.z = 0; hudPlane.position.y = -0.05 hud.add(hudPlane) @@ -86,8 +86,8 @@ class DashBoard { transparent:true }) ); - textPlane.position.z = -0.25; - textPlane.position.y = -0.46 + textPlane.position.z = -0.002; + textPlane.position.y = -0.41 textPlane.visible = false; dash.add(textPlane) })() @@ -115,7 +115,8 @@ class DashBoard { engine.addEventListener('beforeRender', ()=>{ dash.quaternion.copy(engine.camera.quaternion) dash.position.copy(engine.camera.position) - dash.translateZ(-1.2 * engine.camera.zoom); + //dash.translateZ(-1.2 * engine.camera.zoom); + dash.translateZ(-0.5/Math.tan(engine.camera.fov/2 * Math.PI/180) * engine.camera.zoom); }) this.updateText = function(t, textScrolledCallback){ @@ -147,7 +148,7 @@ class DashBoard { levelProgress = new ProgressBar(engine) dash.add(levelProgress.object); - levelProgress.object.position.set(-engine.aspect/2 + engine.aspect/30, 0.45, -0.01) + levelProgress.object.position.set(-engine.aspect/2 + engine.aspect/30, 0.45, -0.001) levelProgress.object.scale.set(engine.aspect/3, 0.02, 0.02) this.levelProgress = levelProgress; diff --git a/src/lib/GameEngine.js b/src/lib/GameEngine.js index 3aebae2..cacc782 100644 --- a/src/lib/GameEngine.js +++ b/src/lib/GameEngine.js @@ -126,7 +126,7 @@ class GameEngine extends THREE.EventDispatcher{ } this.orbitControls = controls; - //controls.enableZoom = true; + controls.enableZoom = false; //const controls = new MapControls( camera, renderer.domElement ); this.transformControls = new TransformControls(this.camera, renderer.domElement); this.transformControls.addEventListener('dragging-changed', function (event) { @@ -179,7 +179,13 @@ class GameEngine extends THREE.EventDispatcher{ //console.log('GameEngine started') renderer.domElement.addEventListener('wheel', (event) => { if (gameEngine.hero){ - gameEngine.hero.cameraZ += event.deltaY / 100; + if (!gameEngine.hero.pointerControls.controls.isLocked){ + gameEngine.hero.cameraZ += event.deltaY / 100; + }else{ + gameEngine.camera.fov += event.deltaY / 100; + gameEngine.camera.fov = Math.min(Math.max(gameEngine.camera.fov, 0.01), 90); + gameEngine.camera.updateProjectionMatrix(); + } }else{ gameEngine.camera.zoom -= event.deltaY / 1000; gameEngine.camera.zoom = Math.max(gameEngine.camera.zoom, .4); diff --git a/src/lib/Hero.js b/src/lib/Hero.js index fa2c0c5..44fa2a5 100644 --- a/src/lib/Hero.js +++ b/src/lib/Hero.js @@ -13,7 +13,11 @@ class Hero{ } set cameraZ(v){ - this.#cameraZ = Math.min(Math.max(v, 2), 10); + this.#cameraZ = Math.min(Math.max(v, 1), 10); + if (this.#cameraZ == 1){ + this.#cameraZ = 0; + this.lockControls(); + } } fadeDuration = 0.2 @@ -75,7 +79,7 @@ class Hero{ this.cameraY = this.size.y * 1.5; this.direction = this.model.rotation.y; - this.directionVelocity = 0; + //this.directionVelocity = 0; this.actionStart = 0; this.cameraDelta = 0; this.cameraIdleDelta = 0; @@ -100,11 +104,22 @@ class Hero{ } updateCharacterControls(delta) { + let pc = this.pointerControls; + if (pc.controls.isLocked && this.model.visible){ + this.model.visible = false; + this.camera.rotation.reorder('YXZ'); + } + if (!pc.controls.isLocked && !this.model.visible){ + this.model.visible = true; + this.#cameraZ = 5/1.77 + this.camera.fov = 45; + this.camera.updateProjectionMatrix(); + } let input = this.getInput() let play = this.currentAction || 'idle', velocity = this.walkVelocity; this.fadeDuration = 0.2; - if (input[1] && this.pointerControls.running) { + if (input[1] && pc.running) { play = 'run'; velocity = this.runVelocity } else if (input[1] > 0) { @@ -152,23 +167,33 @@ class Hero{ } this.actionStart += delta; - this.cameraDelta += delta * ( this.pointerControls.cameraLeft * -1 + this.pointerControls.cameraRight * 1) - this.walkDirection.x = this.walkDirection.y = this.walkDirection.z = 0 + this.cameraDelta += delta * ( pc.cameraLeft * -1 + pc.cameraRight * 1) + this.walkDirection.setScalar(0); - if (this.pointerControls.kb.KeyR && this.cameraY < 5){ + if (pc.kb.KeyR && this.cameraY < 5){ this.cameraY+=delta; } - if (this.pointerControls.kb.KeyF && this.cameraY > 1){ + if (pc.kb.KeyF && this.cameraY > 1){ this.cameraY-=delta; } - if (this.pointerControls.motion) { - this.directionVelocity = this.directionVelocity * 2.5 * Math.abs(input[0]) - this.direction += input[0] * delta * 2.5 //this.directionVelocity; - this.model.rotation.y = this.direction; - this.walkDirection.set(0, 0, input[1]) - this.walkDirection.applyAxisAngle(this.rotateAngle, this.direction) + if (pc.motion){ + if (!pc.controls.isLocked){ + //this.directionVelocity = this.directionVelocity * 2.5 * Math.abs(input[0]) + this.direction += input[0] * delta * 2.5 //this.directionVelocity; + this.walkDirection.set(0, 0, input[1]) + this.walkDirection.applyAxisAngle(this.rotateAngle, this.direction) + }else{ + this.direction = this.camera.rotation.y + Math.PI; + this.walkDirection.set(input[0], 0, input[1]) + this.walkDirection.applyAxisAngle(this.rotateAngle, this.direction) + //console.log(this.camera.rotation.y * 180/Math.PI); + // this.camera.getWorldDirection(this.walkDirection); + // this.walkDirection.applyAxisAngle(this.rotateAngle, input[0]*Math.PI/2 + (input[1]<0 ? Math.PI : 0)) + //this.walkDirection.multiplyScalar(input[1]); + } this.walkDirection.normalize(); + this.model.rotation.y = this.direction; } this.walkDirection.x = this.walkDirection.x * velocity * delta// + this.model.position.x @@ -203,18 +228,20 @@ class Hero{ let cameraPosition = new Vector3().copy(this.camera.position) let cameraDesiredPosition = new Vector3( this.model.position.x + this.#cameraZ* Math.sin(this.model.rotation.y + Math.PI + this.cameraDelta + this.cameraIdleDelta), - this.cameraY + this.model.position.y, + pc.controls.isLocked? this.size.y*0.9 : (this.cameraY + this.model.position.y), this.model.position.z + this.#cameraZ* Math.cos(this.model.rotation.y + Math.PI + this.cameraDelta + this.cameraIdleDelta) ) cameraPosition.lerp(cameraDesiredPosition, delta*2) this.camera.position.copy(cameraPosition) - this.orbitControl.target.set( - this.model.position.x, - this.cameraY -this.size.y * 0.5 + this.model.position.y, - this.model.position.z - ) - this.camera.lookAt(this.orbitControl.target) + if (!pc.controls.isLocked){ + this.orbitControl.target.set( + this.model.position.x, + this.cameraY -this.size.y * 0.5 + this.model.position.y, + this.model.position.z + ) + this.camera.lookAt(this.orbitControl.target) + } } getInput() { diff --git a/src/lib/PointerControls.js b/src/lib/PointerControls.js index fbfbc53..bdc8bd0 100644 --- a/src/lib/PointerControls.js +++ b/src/lib/PointerControls.js @@ -1,5 +1,4 @@ import { Vector3 } from 'three'; - import { PointerLockControls } from 'three/examples/jsm/Addons.js'; class PointerControls {