欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

three.js 第一人称移动。与cs控制角色移动一样(第一人称旋转相机+控制相机移动)

程序员文章站 2024-03-16 20:16:28
...

1注意:我是看官方案例写的,但是我是在vue上面写的,所以如果你不是用vue来做,有些东西需要自己改动。比如有些地方必须让this改为that,不然报错。个人建议如果有,会被其他方法修改的全部都改成 let that=this。

2实现第一人称代码,主要看initMobile()//移动+initControls()//旋转相机+render()的代码。

<template>
  <div>
    <div id="container"></div>
  </div>
</template>

<script>
  import * as Three from '../../node_modules/three/build/three.module.js';
  //import * as Three from 'three'
  import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
  import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
  export default {
    name: 'ThreeTest',
    data() {
      return {
        camera: null,
        scene: null,
        renderer: null,
        mesh: null,
        controls:"",
        intersections:null,
        objects : [],
        clock:"",
        moveForward:false,
        moveLeft:false,
        moveBackward:false,
        moveRightInit:false,
        direction : new Three.Vector3(),
        velocity : new Three.Vector3(),
        prevTime : performance.now()
      }
    },
    methods: {
      init: function() {
        this.initScene()//场景对象
        this.initCamera()//相机
        this.initWebGLRenderer()//渲染器
        this.initAxisHelper()//辅助坐标
        this.render()
        this.createControls()//控件对象
        this.Box()
        this.initControls()//相机视角
        this.initPlane()//地板
        this.initMobile()//移动
      },
      //鼠标控制移动相机视角*****
      initControls(){
        let that=this
        that.controls = new PointerLockControls( this.camera, document.body );
        var container = document.getElementById( 'container' );
        container.addEventListener( 'click', function () {
          that.controls.lock();
        });
        this.scene.add(that.controls.getObject() );
      },
      //移动
      initMobile(){
        let that=this
        console.log(this.controls)
        var onKeyDown = function ( event ) {

          switch ( event.keyCode ) {

            case 38: // up
            case 87: // w
              that.moveForward = true;
              break;

            case 37: // left
            case 65: // a
              that.moveLeft = true;
              break;

            case 40: // down
            case 83: // s
              that.moveBackward = true;
              break;

            case 39: // right
            case 68: // d
              that.moveRightInit = true;
              break;

          }

        };

        var onKeyUp = function ( event ) {

          switch ( event.keyCode ) {

            case 38: // up
            case 87: // w
              that.moveForward = false;
              break;

            case 37: // left
            case 65: // a
              that.moveLeft = false;
              break;

            case 40: // down
            case 83: // s
              that.moveBackward = false;
              break;

            case 39: // right
            case 68: // d
              that.moveRightInit = false;
              break;

          }

        };

        document.addEventListener( 'keydown', onKeyDown, false );
        document.addEventListener( 'keyup', onKeyUp, false );
      },
      创建场景对象Scene
      initScene(){
        this.scene = new Three.Scene();
      },
      相机
      initCamera(){
        let container = document.getElementById('container');
        this.camera = new Three.PerspectiveCamera(60, container.clientWidth/container.clientHeight, 1, 1000);
        this.camera.position.set(292, 109, 268);//设置相机位置
        this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
      },
      Box(){
        //正方形
        let geometry = new Three.BoxGeometry(50, 50, 50);
        let material = new Three.MeshNormalMaterial();
        this.mesh = new Three.Mesh(geometry, material);
        this.scene.add(this.mesh);
      },
      //地板
      initPlane(){
        var planeGeometry = new Three.PlaneGeometry(600, 600);
        //平面使用颜色为0xcccccc的基本材质
        var planeMaterial = new Three.MeshBasicMaterial({color: 0xcccccc});
        var plane = new Three.Mesh(planeGeometry, planeMaterial);
        //设置屏幕的位置和旋转角度
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = 0;
        plane.position.z = 0;
        //将平面添加场景中
        this.scene.add(plane);
      },
      //创建渲染器对象
      initWebGLRenderer(){
        this.renderer = new Three.WebGLRenderer({antialias: true});
        this.renderer.setSize(container.clientWidth, container.clientHeight);//设置渲染区域尺寸
        this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
        container.appendChild(this.renderer.domElement);//body元素中插入canvas对象
      },
      //辅助三维坐标系AxisHelper
      initAxisHelper(){
        this.axisHelper = new Three.AxisHelper(250);
        this.scene.add(this.axisHelper);
      },
      render:function(){
        let that=this
        //this.mesh.rotation.x+=0.01
        requestAnimationFrame(that.render); //请求再次执行渲染函数render
        that.renderer.render(that.scene,that.camera);//执行渲染操作

        //从这开始下面**就是控制移动的代码
        let time = performance.now();
        let delta = ( time - that.prevTime ) / 1000;

        that.velocity.x -= that.velocity.x * 10.0 * delta;
        that.velocity.z -= that.velocity.z * 10.0 * delta;

        that.direction.z = Number( that.moveForward ) - Number( that.moveBackward );
        that.direction.x = Number( that.moveRightInit ) - Number( that.moveLeft );

        that.velocity.z -= that.direction.z * 400.0 * delta;
        that.velocity.x -= that.direction.x * 400.0 * delta;

        //下面两个&&是判断是否有moveRight。如果有就执行。不然没加载完毕,就循环执行会报错
        that.controls && that.controls.moveRight(- that.velocity.x * delta)
        that.controls && that.controls.moveForward(- that.velocity.z * delta)
        that.prevTime = time;
      },
      // 创建控件对象
      createControls () {
        this.controls = new OrbitControls(this.camera,this.renderer.domElement)
      }

    },
    mounted() {
      this.init();
      this.render();

    }
  }
</script>
<style scoped>
  #container {
    height: 400px;
  }
</style>
相关标签: three.js