Procházet zdrojové kódy

视野随按住的鼠标移动,用WSAD在平面上移动

zachary před 4 roky
rodič
revize
ccc1acca99
4 změnil soubory, kde provedl 101 přidání a 17 odebrání
  1. 1 1
      dist/main.js
  2. binární
      resource/collision-world.glb
  3. 100 5
      src/index.js
  4. 0 11
      src/listener.js

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 1
dist/main.js


binární
resource/collision-world.glb


+ 100 - 5
src/index.js

@@ -1,8 +1,10 @@
 const THREE = require('three');
 import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
 import { Octree } from 'three/examples/jsm/math/Octree.js';
-import { onDocumentMouseMove,onWindowResize } from './listener';
+import { Capsule } from 'three/examples/jsm/math/Capsule.js';
 
+
+const clock = new THREE.Clock();
 //1.建立场景
 const scene = new THREE.Scene();
 scene.background = new THREE.Color(0x88ccff);
@@ -26,6 +28,7 @@ const container = document.getElementById('container');
 container.appendChild(renderer.domElement);
 
 const keyStates = {};
+const STEPS_PER_FRAME = 5;  //一帧多少步
 
 document.addEventListener('resize',onWindowResize,false);
 document.addEventListener( 'keydown', ( event ) => {
@@ -41,17 +44,88 @@ document.addEventListener('mouseup',(event) => {
     document.removeEventListener('mousemove',onDocumentMouseMove);
 })
 
+//添加游客
+const worldOctree = new Octree();
+
+const playerCollider = new Capsule( new THREE.Vector3( 0, 0.35, 0 ), new THREE.Vector3( 0, 1, 0 ), 0.35 ); 
+const playerVelocity = new THREE.Vector3();
+const playerDirection = new THREE.Vector3();
+
+function playerCollisions(){
+    const result = worldOctree.capsuleIntersect(playerCollider);
+    if(result){
+        playerCollider.translate(result.normal.multiplyScalar( result.depth ));
+    }
+}
+
+function updatePlayer(deltaTime){
+    const deltaPosition = playerVelocity.clone().multiplyScalar(deltaTime);
+    playerCollider.translate(deltaPosition);       //向量相加
+    playerCollisions();
+    camera.position.copy(playerCollider.end);
+}
+
+function getForwardVector() {
+
+    camera.getWorldDirection( playerDirection );
+    playerDirection.y = 0;
+    playerDirection.normalize();       //将该向量转换为单位向量
+
+    return playerDirection;
+
+}
+
+function getSideVector() {
+
+    camera.getWorldDirection( playerDirection );
+    playerDirection.y = 0;
+    playerDirection.normalize();
+    playerDirection.cross( camera.up );
+
+    return playerDirection;
+
+}
+
+
+function controls( deltaTime ) {
+
+    const speed = 2;
+
+    if ( keyStates[ 'KeyW' ] ) {
+
+        playerVelocity.add( getForwardVector().multiplyScalar( speed * deltaTime ) );
 
+    }
 
+    if ( keyStates[ 'KeyS' ] ) {
 
+        playerVelocity.add( getForwardVector().multiplyScalar( - speed * deltaTime ) );
 
+    }
+
+    if ( keyStates[ 'KeyA' ] ) {
+
+        playerVelocity.add( getSideVector().multiplyScalar( - speed * deltaTime ) );
+
+    }
+
+    if ( keyStates[ 'KeyD' ] ) {
+
+        playerVelocity.add( getSideVector().multiplyScalar( speed * deltaTime ) );
+
+    }
+
+}
 
 let loader = new GLTFLoader();
-loader.load('../resource/scene.gltf',function(gltf){
+loader.load('../resource/collision-world.glb',function(gltf){
     const model = gltf.scene;
-    model.position.set( 1, 1, 0);
-    model.scale.set( 0.01, 0.01, 0.01 );
+    // model.position.set( 1, 1, 0);
+    // model.scale.set( 0.1, 0.1, 0.1 );
     scene.add(model);
+
+    worldOctree.fromGraphNode( model );
+
     animate();
 },undefined,function(error){
     console.error(error);
@@ -59,6 +133,27 @@ loader.load('../resource/scene.gltf',function(gltf){
 
 // 5.渲染场景
 function animate(){
-    requestAnimationFrame( animate );
+    const deltaTime = Math.min( 0.05, clock.getDelta() ) / STEPS_PER_FRAME;
+    for ( let i = 0 ; i < STEPS_PER_FRAME ; i ++ ) {
+
+        controls( deltaTime );
+
+        updatePlayer( deltaTime );
+
+    }
+    
 	renderer.render( scene, camera );
+    requestAnimationFrame( animate );
+}
+
+
+function onDocumentMouseMove(event){
+    camera.rotation.y -= event.movementX / 500;
+	camera.rotation.x -= event.movementY / 500;
+}
+
+function onWindowResize() {
+    camera.aspect = window.innerWidth / window.innerHeight;
+    camera.updateProjectionMatrix();    						//更新摄像机投影矩阵。在任何参数被改变以后必须被调用。
+    renderer.setSize( window.innerWidth, window.innerHeight );
 }

+ 0 - 11
src/listener.js

@@ -1,11 +0,0 @@
-export function onDocumentMouseMove(event){
-    camera.rotation.y -= event.movementX / 500;
-	camera.rotation.x -= event.movementY / 500;
-}
-
-export function onWindowResize() {
-    camera.aspect = window.innerWidth / window.innerHeight;
-    camera.updateProjectionMatrix();    						//更新摄像机投影矩阵。在任何参数被改变以后必须被调用。
-    renderer.setSize( window.innerWidth, window.innerHeight );
-}
-