three.js 鼠标左右拖动改变玩家视角

时间:2024-03-14 09:54:39

这里主要用到了 一个方法   obj.getWorldDirection();  

obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。

按下 W键前进运动;

 

<template>
  <div>
    <el-container>
      <el-main>
        <div class="box-card-left">
          <div id="threejs"></div>
          {{ movementX }}
        </div>
      </el-main>
    </el-container>
  </div>
</template>s
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import TWEEN from '@tweenjs/tween.js';
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      res1: null,
      res2: null,
      clock: null,
      left_mouse_down: false,
      keyState: {
        W: false,
        S: false,
        A: false,
        D: false,
      },
      left_rotation: true, // 向左旋转的标志
      right_rotation: true, // 向右旋转的标志
      VW: new this.$three.Vector3(0, 0, 0),
      VS: new this.$three.Vector3(0, 0, 0),
      curr_v: new this.$three.Vector3(0, 0, 0),
      person: null,
      movementX: null,
      deltaTime: 0,
      a: 60, // 加速度
      damping: -0.04,
    };
  },
  created() {},
  mounted() {
    this.init();
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
    init() {
      // 创建场景对象
      this.scene = new this.$three.Scene();
      // 创建坐标轴辅助对象
      const axesHelper = new this.$three.AxesHelper(100);
      this.scene.add(axesHelper);
      // 创建时钟对象
      this.clock = new this.$three.Clock();
      // 创建环境光对象
      const ambientLight = new this.$three.AmbientLight(0xffffff, 6);
      this.scene.add(ambientLight);
      // this.createMesh();
      // 创建相机对象
      this.camera = new this.$three.PerspectiveCamera(60,1,0.01,2000);
      // this.camera.position.set(0,5,-5);
      // this.camera.lookAt(0,0,0);
      // 创建渲染器对象
      this.renderer = new this.$three.WebGLRenderer();
      this.renderer.setSize(1000,800);
      // 创建gltfLoader加载器对象
      const gltfLoader = new GLTFLoader();
      gltfLoader.load("models/gltf/person2/scene.gltf", gltf => {
        this.person = gltf.scene;
        // 将相机添加到人物模型上
        this.person.add(this.camera);
        // 调整相机位置
        this.camera.position.add(new this.$three.Vector3(0,5,-6));
        this.camera.translateZ(-1);
        let camera_look_position = this.person.position.clone().add(new this.$three.Vector3(0,4,0));
        // 设置相机指向
        this.camera.lookAt(camera_look_position);
        this.scene.add(gltf.scene);
        this.renderer.render(this.scene, this.camera);
        window.document.getElementById("threejs").appendChild(this.renderer.domElement);
      })
      // 监听事件方法
      this.addEventListenerFn();
      this.renderLoop();
    },
    createMesh() {
      const geometry = new this.$three.BoxGeometry(1,1,1);
      const material = new this.$three.MeshBasicMaterial({color: 0xffaadd});
      const mesh = new this.$three.Mesh(geometry, material);
      // mesh.rotateY(Math.PI / 2);
      const dir = new this.$three.Vector3();
      mesh.getWorldDirection(dir);
      this.scene.add(mesh);
      console.log('dir', dir);
    },
    addEventListenerFn() {
      document.addEventListener("mousemove", e => {
        // 鼠标左键按下的情况
        if(this.left_mouse_down) {
          this.movementX = e.movementX;
          this.person.rotation.y -= e.movementX / 100;
          // this.camera.rotateY(e.movementX / 100);
        const dir = new this.$three.Vector3();
        this.person.children[0].getWorldDirection(dir);
          this.renderer.render(this.scene, this.camera);
        }
      })
      document.addEventListener("mousedown", e => {
        // e.button == 0 左键;e.button == 2 右键;
        if(e.button == 0) {
          this.left_mouse_down = true;
        }
      })
      document.addEventListener("mouseup", e => {
        // e.button == 0 左键;e.button == 2 右键;
        if(e.button == 0) {
          this.left_mouse_down = false;
        }
      })
      // 监听键盘按下
      document.addEventListener("keydown", e => {
        // 如果按下的是  w键
        if(e.code == "KeyW") {
          this.keyState.W = true;
        }
        if(e.code == "KeyS") {
          this.keyState.S = true;
        }
      })
      // 监听键盘弹起
      document.addEventListener("keyup", e => {
        // 如果按下的是  w键
        if(e.code == "KeyW") {
          this.keyState.W = false;
        }
        if(e.code == "KeyS") {
          this.keyState.S = false;
        }
      })
    },
    renderLoop() {
      let deltaTime = this.clock.getDelta();

      if(this.keyState.W) {
        const front = new this.$three.Vector3();
        this.person.getWorldDirection(front);
        let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * this.a));
        const pos = person_v.clone().multiplyScalar(deltaTime);
        this.person.position.add(pos);
      }
      if(this.keyState.S) {
        const front = new this.$three.Vector3();
        this.person.getWorldDirection(front);
        let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * (-this.a)));
        const pos = person_v.clone().multiplyScalar(deltaTime);
        this.person.position.add(pos);
      }
      this.renderer.render(this.scene, this.camera);
      window.requestAnimationFrame(this.renderLoop);
    },
  },
};
</script>
<style lang="less" scoped>
.box-card-left {
  display: flex;
  align-items: flex-start;
  flex-direction: row;
  width: 100%;
  .box-right {
    img {
      width: 500px;
      user-select: none;
    }
  }
}
</style>