0

这是我的第一个三个 js 第一人称视角游戏,当我转动相机时遇到问题,枪不跟随我正在看的相机旋转。

这是现场网站的链接:https : //geniussniper.github.io/Glory/ 按下 0 将显示相机旋转和枪位按下 y 可以控制环顾“asdw”以进行移动

这是我的代码

import * as THREE from 'three';
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

class World {
    constructor(){
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

        this.clock = new THREE.Clock();

        this.world = {
            player: {
                x: 0, // a,d side way control
                y: 30, // flying cheating control
                z: 0, // w,s forward backward control
                // canShoot: 0,
            },
            movementSpeed: .4,
            size: 1000,
            camera: {
                y: 10
            },
            bullets: [],
            timer: 0
        }
        
        this.renderer = new THREE.WebGLRenderer({
            antialias: true
        });
        
        this.hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1 );
        this.scene.add( this.hemisphereLight );
        this.directionalLight = new THREE.DirectionalLight(0xffffff)
        this.scene.add(this.directionalLight);

        this.keyborad = [];

        addEventListener('keydown', e => {
            this.keyborad[e.key] = true;
        });

        addEventListener('keyup', e => {
            this.keyborad[e.key] = false;
        });

        addEventListener( 'click', () => {
            if(this.pistol){
                let bullet = new THREE.Mesh(
                    new THREE.SphereGeometry(0.05, 8, 8),
                    new THREE.MeshBasicMaterial({color: 0xffffff})
                );
                bullet.position.set(
                    this.pistol.position.x,
                    this.pistol.position.y + 0.4,
                    this.pistol.position.z
                )

                bullet.velocity = new THREE.Vector3(
                    -Math.sin(this.camera.rotation.y),
                    0,
                    Math.cos(this.camera.rotation.y)
                );

                bullet.alive = true;
                setTimeout(() => {
                    bullet.alive = false;
                    this.scene.remove(bullet);
                }, 1000);

                this.world.bullets.push(bullet);
                this.scene.add(bullet);
            }
        }, false );

        this.loader = new GLTFLoader();


        this.render();
    }

    animate() {
        requestAnimationFrame( () => this.animate() );

        this.processKeyboard();

        // this.controls.update(); //OrbitControls for not following charater

        this.shotting();

        this.renderer.render( this.scene, this.camera );        
    }

    shotting() {
        for( let i = 0; i < this.world.bullets.length; i++){
            if(this.world.bullets[i] === undefined) continue;
            if(this.world.bullets[i].alive === false){
                this.world.bullets.splice(i, 1);
                continue;
            }
            this.world.bullets[i].position.add(this.world.bullets[i].velocity);
        }
    }

    worldSetup() {
        this.renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( this.renderer.domElement );
        this.camera.position.setY(10);
        this.camera.position.setZ(30);
            
        // this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls = new PointerLockControls(this.camera, this.renderer.domElement);
    
        this.loader.load('./src/models/game_pirate_adventure_map/scene.gltf', (gltf) => {
            gltf.scene.scale.set(0.01, 0.01, 0.01);
            this.scene.add(gltf.scene);
        });   

        this.loader.load('./src/models/vis_p35p_pistol/scene.gltf', (gltf) => {
            gltf.scene.scale.set(0.01, 0.01, 0.01);
            gltf.scene.position.set(0, 8, 34);
            this.pistol = gltf.scene;
            this.scene.add(this.pistol);
        }); 

        window.addEventListener( 'resize', () => {
            this.camera.aspect = window.innerWidth / window.innerHeight;
            this.camera.updateProjectionMatrix();
            this.renderer.setSize( window.innerWidth, window.innerHeight );
        }, false );
    }

    processKeyboard() {
        let time = Date.now() * 0.0005;
        if(this.keyborad['w']){
            this.controls.moveForward(this.world.movementSpeed);
        }
        if(this.keyborad['s']) {
            this.controls.moveForward(-this.world.movementSpeed);
        }
        if(this.keyborad['a']){
            this.controls.moveRight(-this.world.movementSpeed);
        }
        if(this.keyborad['d']) {
            this.controls.moveRight(this.world.movementSpeed);
        }
        if(this.keyborad['y']){
            this.controls.lock();
        }
        if(this.keyborad['esc']) {
            this.controls.unlock();
        }
        if(this.keyborad['0']){
            //the debugging console
            if(this.world.timer <= 0){
                // console.log(this.camera.position);
                console.log(this.camera.rotation);
                console.log(this.pistol.position);
                // console.log(this.pistol.rotation);
                this.world.timer = 10;
            } else {
                this.world.timer -= 1;
            }
        }
        if(this.pistol){
            let rotation = this.camera.rotation.y + Math.PI/6
            this.pistol.position.set(
                this.camera.position.x - Math.sin(rotation) * 4, 
                this.camera.position.y - 1 + Math.sin(time * 4 + this.camera.position.x + this.camera.position.z) * 0.04, 
                this.camera.position.z + Math.cos(rotation) * 4
            )
            this.pistol.rotation.set(
                this.camera.rotation.x,
                this.camera.rotation.y - Math.PI/2,
                this.camera.rotation.z
            )
        }
    }

    render() {    
        this.worldSetup();
        this.camera.lookAt(new THREE.Vector3(0, this.world.camera.y, 40))
        this.animate();
    };

}

export default World;
4

0 回答 0