three.js应用篇(五)模型内第一视角漫游

在web端3D的交互中,第一视角漫游(类似于CF游戏射击视角)也是基础功能之一,在three.js的应用中将这个功能拆解一下,无非包括以下几点:

1、锁定摄像机的lookAt方向,让方向跟随鼠标

2、监听键盘,通过更改摄像机的位置模拟进行移动

3、监听空格键的跳跃时,需要进行下落操作

4、不停用渲染器重复渲染,达到平滑视角的目的

下面直接上关键代码(完整代码见附件),静态的html中js有跨域问题,需要使用编辑器打开运行示例

///
    ///
    ///第一视角核心代码//
    ///
    ///

    let pointerLockControls = new THREE.PointerLockControls(camera,document.body);
    // 需要锁定的父盒子
    let blocker = document.getElementById("content");
    // 进行监听的内容盒子
    let instructions = document.getElementById("instructions");
    //第一人称视角使用变量
    const objects = [];

    let raycaster;

    let moveForward = false;
    let moveBackward = false;
    let moveLeft = false;
    let moveRight = false;
    let canJump = false;

    let prevTime = performance.now();
    const velocity = new THREE.Vector3();
    const direction = new THREE.Vector3();
    instructions.addEventListener( 'click', function () {
        console.log("点击了主屏幕,应该锁定");
        //pointerLockControls.lock();
        pointerLockControls.idLocked = true;
        document.body.requestPointerLock();
    });
    instructions.addEventListener( 'lock', function (){
        instructions.style.display = 'none';
        blocker.style.display = 'none';
    });
    instructions.addEventListener( 'unlock', function (){
        pointerLockControls.idLocked = false;
        blocker.style.display = 'block';
        instructions.style.display = '';
    });
    scene.add( pointerLockControls.getObject() );
    const onKeyDown = function ( event ) {

        switch ( event.code ) {

            case 'ArrowUp':
            case 'KeyW':
                moveForward = true;
                break;

            case 'ArrowLeft':
            case 'KeyA':
                moveLeft = true;
                break;

            case 'ArrowDown':
            case 'KeyS':
                moveBackward = true;
                break;

            case 'ArrowRight':
            case 'KeyD':
                moveRight = true;
                break;

            case 'Space':
                if ( canJump === true ) velocity.y += 350;
                canJump = false;
                break;

        }

    };

    const onKeyUp = function ( event ) {
        switch ( event.code ) {
            case 'ArrowUp':
            case 'KeyW':
                moveForward = false;
                break;

            case 'ArrowLeft':
            case 'KeyA':
                moveLeft = false;
                break;

            case 'ArrowDown':
            case 'KeyS':
                moveBackward = false;
                break;

            case 'ArrowRight':
            case 'KeyD':
                moveRight = false;
                break;
        }
    };
    document.addEventListener( 'keydown', onKeyDown );
    document.addEventListener( 'keyup', onKeyUp );
    raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 );


    //窗口变动触发的函数
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        render();
        renderer.setSize( window.innerWidth, window.innerHeight );
    }

    let clock = new THREE.Clock();
    function render(){

        renderer.clear();

        const time = performance.now();
        if ( true ) {
            console.log("进入动画");

            raycaster.ray.origin.copy( pointerLockControls.getObject().position );
            raycaster.ray.origin.y -= 10;

            const intersections = raycaster.intersectObjects( objects );

            const onObject = intersections.length > 0;

            const delta = ( time - prevTime ) / 1000;

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

            velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass

            direction.z = Number( moveForward ) - Number( moveBackward );
            direction.x = Number( moveRight ) - Number( moveLeft );
            direction.normalize(); // this ensures consistent movements in all directions

            if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * delta;
            if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * delta;

            if ( onObject === true ) {

                velocity.y = Math.max( 0, velocity.y );
                canJump = true;

            }

            pointerLockControls.moveRight( - velocity.x * delta );
            pointerLockControls.moveForward( - velocity.z * delta );

            pointerLockControls.getObject().position.y += ( velocity.y * delta );

            if ( pointerLockControls.getObject().position.y < 10 ) {

                velocity.y = 0;
                pointerLockControls.getObject().position.y = 10;

                canJump = true;

            }

        }

        prevTime = time;

        requestAnimationFrame(render);
        renderer.render(scene,camera);//执行渲染操作
        window.onresize = onWindowResize;

    }
    render();

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Three.js是一个用于创建3D场景的JavaScript库,它提供了许多强大的功能,包括创建3D模型、灯光、材质、动画等。在three.js中,我们可以使用相机对象来控制我们的视角。 首先,我们需要定义一个场景和一个相机。代码如下: ```javascript var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); ``` 这里创建了一个场景对象和一个透视相机对象。透视相机是一种透视投影,能够产生3D效果。第一个参数75是相机的视角,第二个参数是相机的宽高比,第三个和第四个参数是相机的近和远裁剪面。 接着,我们需要创建一个渲染器对象,将其添加到页面上: ```javascript var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); ``` 这里创建了一个WebGL渲染器对象,并将其添加到页面中。渲染器在场景中渲染图像,并将其呈现到页面上。 现在,我们可以创建一个立方体对象,并将其添加到场景中: ```javascript var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); var cube = new THREE.Mesh(geometry, material); scene.add(cube); ``` 这里创建了一个立方体几何体对象,一个绿色的材质对象,并将它们组合成一个网格对象。最后,将网格对象添加到场景中。 现在,我们可以定义一个渲染函数进行渲染。渲染函数应该在动画循环中被调用: ```javascript function render() { requestAnimationFrame(render); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } render(); ``` 这里定义了一个渲染函数,使用requestAnimationFrame方法在动画循环中调用。在函数中,我们旋转立方体对象,并使用渲染器对象将场景呈现到页面上。 最后,我们需要添加一些控制器来控制相机的位置和方向。three.js提供了一些内置的控制器,例如OrbitControls和FlyControls。我们可以使用这些控制器来实现第一人称视角漫游。以下是使用OrbitControls实现第一人称视角漫游的示例代码: ```javascript var controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.25; controls.screenSpacePanning = false; controls.minDistance = 1; controls.maxDistance = 50; controls.maxPolarAngle = Math.PI / 2; camera.position.set(0, 10, 20); controls.update(); ``` 这里创建了一个OrbitControls控制器,并将其绑定到相机对象和渲染器对象上。控制器具有一些属性,例如dampingFactor和maxPolarAngle,我们可以根据需要进行调整。最后,我们将相机的位置设置为(0,10,20),并更新控制器。 这样,我们就完成了第一人称视角漫游的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值