• WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制


    接上一节,游戏控制首先要解决的就是碰撞检测了

    这里用到了学习笔记(三)射线检测的内容了

    以鸟为射线原点,向前、上、下分别发射3个射线,射线的长度较短大概为10~30.

    根据上一节场景的建设,我把y轴设为前进方向,z轴设为高度~

    如果射线返回有结果,那么说明鸟遇到了障碍物。代码如下:

                    var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
                    var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
                    var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
                    //
                    var intersections1 = raycaster1.intersectObjects(objects);
                    var intersections2 = raycaster2.intersectObjects(objects);
                    var intersections3 = raycaster3.intersectObjects(objects);
                    //如果前方有物体,向前速度为0                              
                    if (intersections1.length > 0)
                    {
                        velocity.y = 0;
                    }
    
                    //如果上方有物体,向上速度为0或为负值 
                    if (intersections2.length > 0 )
                    {
                        if (velocity.z > 0)
                        {
                            velocity.z = 0;
                        }
                        
                    }
                    //如果下方有物体,向下速度为0或为正值
                    if (intersections3.length > 0) {
                        if (velocity.z < 0)
                        {
                            velocity.z = 0;
                        }
    
                    }
    
                    if (birdmesh.position.z < 10)
                    {
                        birdmesh.position.z = 10;
                    }
    
                    if (birdmesh.position.z > 575) {
                        birdmesh.position.z = 575;
                    }
    
    
                    if (velocity.y==0)
                    {
                        alert('您已死亡!');
                    }

    其次需要解决的就是飞行前进和重力下降的问题

    首先新建一个

    var velocity = new THREE.Vector3();

    用velocity.x和.y以及.z来表示像3个方向的速度。

    y方向为前进方向,给定一个固定值就行,检测到碰撞停止。

    x方向不用管,因为x方向没有运动。

    z方向为高度方向,要做到鼠标点击飞高一段距离,然后重力下降。

    首先鼠标点击给定一个固定的向上的速度,然后速度加速递减(重力效果),代码如下

     
                        window.addEventListener('mousedown', function (event) {

                            velocity.z = 500;
                            mixer.clipAction(clip).setDuration(0.1).play();
                            
                            
                           
                        }, false);

                        window.addEventListener('mouseup', function (event) {
                            
                            mixer.clipAction(clip).setDuration(1).play();

                        }, false);




    var delta = clock.getDelta(); //这里100就是速度的一个因子,数值越大,重力效果越明显; velocity.z -= 9.8 * 100 * delta; birdmesh.position.z += velocity.z*delta; birdmesh.position.y += velocity.y * delta; velocity.y = 200;



    另外上面代码仔细观察,你会发现鼠标点击和松开给定的鸟煽动翅膀的速度是不一样的

    mixer.clipAction(clip).setDuration(1).play()

    这是为了达到点击鼠标有鸟在努力向上飞的视觉效果~。

    先写到这。全部源码先贴在这吧,其实上传工程的效果是最好的,但还没整理好。这个练手还没完!

    预告后面两节

    后1节:飞行类小游戏转置为win10通用UWP应用(我将上传至微软商店,敬请期待!)

    后2节:飞行类小游戏转置为手机安卓应用

    最后目前全部源码~

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>练手</title>
        <meta charset="utf-8">
        
    
    </head>
    <body>
    
        <script src="build/three.js"></script>
        <script src="js/Detector.js"></script>
    
        <script src="js/controls/OrbitControls.js"></script>
    
    
        <script>
            if (!Detector.webgl) Detector.addGetWebGLMessage();
    
    
    
                var camera, scene, renderer;
    
                var clock = new THREE.Clock();
                //var controls;
    
                var velocity = new THREE.Vector3();
                var birdmesh;
                var objects = [];
                init();
                animate();
    
    
                function init()
                {
                    container = document.createElement( 'div' );
                    document.body.appendChild( container );
    //
                    camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 100000);                
                    camera.up.set(0, 0, 1);
                    camera.lookAt(new THREE.Vector3(-1, 1, 0));
    
                    scene = new THREE.Scene();
    //
                    scene.add( new THREE.HemisphereLight( 0x443333, 0x222233 ) );
                    var light = new THREE.DirectionalLight( 0xffffff, 1 );
                    light.position.set( 1, 1, 1 );
                    scene.add( light );
                    //------添加内容
    
    
                    //---地板,平面
                    geometry = new THREE.PlaneGeometry(512, 200000);
                    
                    //geometry.rotateX(-Math.PI / 2);
                     
    
                    var texture = new THREE.TextureLoader().load('img/dd.jpg');
                    texture.wrapS = THREE.RepeatWrapping;
                    texture.wrapT = THREE.RepeatWrapping;
                    texture.repeat.set(8, 800)
                    material = new THREE.MeshBasicMaterial({ map: texture });
    
                    //material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
                    mesh = new THREE.Mesh(geometry, material);
                    mesh.position.set(0, 0, 0);
                    scene.add(mesh);
                    objects.push(mesh);
    
                    ////箱子1
                    //geometry = new THREE.BoxGeometry(2, 2, 2);
                    //material = new THREE.MeshBasicMaterial({color:0x000000});
                    //mesh = new THREE.Mesh(geometry, material);
                    //mesh.position.set(0,0,0);
                    //scene.add(mesh);
    
                    ////箱子2
                    //geometry = new THREE.BoxGeometry(2, 2, 2);
                    //material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
                    //mesh = new THREE.Mesh(geometry, material);
                    //mesh.position.set(100, 0, 0);
                    //scene.add(mesh);
    
                    ////箱子3
                    //geometry = new THREE.BoxGeometry(2, 2, 2);
                    //material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
                    //mesh = new THREE.Mesh(geometry, material);
                    //mesh.position.set(0, 100, 0);
                    //scene.add(mesh);
    
                    ////箱子4
                    //geometry = new THREE.BoxGeometry(2, 2, 2);
                    //material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
                    //mesh = new THREE.Mesh(geometry, material);
                    //mesh.position.set(0, 0, 100);
                    //scene.add(mesh);
    
    
                    //天空盒
                    var textureLoader = new THREE.TextureLoader();
                    var materials = [
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/px.jpg') }), // right
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nx.jpg') }), // left
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/py.jpg') }), // top
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/ny.jpg') }), // bottom
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/pz.jpg') }), // back
                        new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nz.jpg') })  // front
                    ];
                    mesh = new THREE.Mesh(new THREE.BoxGeometry(100000, 100000, 100000, 7, 7, 7), new THREE.MultiMaterial(materials));
                    mesh.scale.x = -1;
                    scene.add(mesh);
    
    
                    //连续障碍物
                    for (var i = 0; i < 50;i++) {
                        var ht=Math.random() * 450;
                        geometry = new THREE.BoxGeometry(80, 20, ht);
                        material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
                        mesh = new THREE.Mesh(geometry, material);
    
                        mesh.position.x =0;
                        mesh.position.y = (i+1) * 500;
                        mesh.position.z = ht / 2;
                        scene.add(mesh);
    
                        objects.push(mesh);
    
    
                        geometry = new THREE.BoxGeometry(80, 20, 450-ht);                    
                        mesh = new THREE.Mesh(geometry, material);                    
                        mesh.position.x = 0;
                        mesh.position.y = (i + 1) * 500;
                        mesh.position.z = ht  + 140 + (450 - ht) / 2;
                        scene.add(mesh);
    
                        objects.push(mesh);
    
    
                    }
    
    
    
    
    
                    //
                    var loader = new THREE.JSONLoader();
    
                    loader.load( "models/animated/flamingo.js", function( geometry ) {
                        geometry.computeVertexNormals();
                        geometry.computeMorphNormals();
                        var material = new THREE.MeshPhongMaterial( {
                            color: 0xffffff,
                            morphTargets: true,
                            morphNormals: true,
                            vertexColors: THREE.FaceColors,
                            shading: THREE.SmoothShading
                        } );
                        birdmesh = new THREE.Mesh( geometry, material );
                        birdmesh.position.x = 0;
                        birdmesh.position.y = 0;
                        birdmesh.position.z = 200;
                        birdmesh.scale.set(0.2, 0.2, 0.2);
                        birdmesh.rotateX(-Math.PI / 2);
                        birdmesh.rotateZ(Math.PI);
                        scene.add(birdmesh);
                        mixer = new THREE.AnimationMixer(birdmesh);
                        
                        
    
                        var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('bd', geometry.morphTargets, 30);
                        mixer.clipAction(clip).setDuration(1).play();
    
    
                        window.addEventListener('mousedown', function (event) {
    
                            velocity.z = 500;
                            mixer.clipAction(clip).setDuration(0.1).play();
                            
                            
                           
                        }, false);
    
                        window.addEventListener('mouseup', function (event) {
                            
                            mixer.clipAction(clip).setDuration(1).play();
    
                        }, false);
    
    
                    } );
                    
    
    
                    renderer = new THREE.WebGLRenderer({ antialias: true });
                    renderer.setPixelRatio(window.devicePixelRatio);
                    renderer.setSize(window.innerWidth, window.innerHeight);
                    container.appendChild( renderer.domElement );
                    
                    //控制
    
                    //var controls = new THREE.OrbitControls(camera, renderer.domElement);
                    //controls.addEventListener('change', render);
                    //controls.target.set(0, 0, 0);
                    //controls.update();
    
                    //
                    window.addEventListener('resize', function onWindowResize(event) {
                        renderer.setSize(window.innerWidth, window.innerHeight);
                        camera.aspect = 0.5 * window.innerWidth / window.innerHeight;
                        camera.updateProjectionMatrix();
                    }, false);
                    
                }
    
    
                //
                function animate() {
                    
                    
                    requestAnimationFrame( animate );
                    render();
    
                }
    
    
            
    
    
                function render() {
                    
                    var delta = clock.getDelta();
    
                    //这里100就是速度的一个因子,数值越大,重力效果越明显,等效于velocity.y =(velocity.y*0.01- 9.8  * delta)*100;
                    velocity.z -= 9.8 * 100 * delta;
    
                    birdmesh.position.z += velocity.z*delta;
                    birdmesh.position.y += velocity.y * delta;
                    
                    velocity.y = 200;
    
                    var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
                    var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
                    var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
                    //
                    var intersections1 = raycaster1.intersectObjects(objects);
                    var intersections2 = raycaster2.intersectObjects(objects);
                    var intersections3 = raycaster3.intersectObjects(objects);
                    //是否检测到               
                    
                    if (intersections1.length > 0)
                    {
                        velocity.y = 0;
                    }
    
                    
                    if (intersections2.length > 0 )
                    {
                        if (velocity.z > 0)
                        {
                            velocity.z = 0;
                        }
                        
                    }
    
                    if (intersections3.length > 0) {
                        if (velocity.z < 0)
                        {
                            velocity.z = 0;
                        }
    
                    }
    
                    if (birdmesh.position.z < 10)
                    {
                        birdmesh.position.z = 10;
                    }
    
                    if (birdmesh.position.z > 575) {
                        birdmesh.position.z = 575;
                    }
    
    
                    if (velocity.y==0)
                    {
                        alert('您已死亡!');
                    }
    
    
                    mixer.update(delta);
    
                    camera.position.set(birdmesh.position.x+100, birdmesh.position.y - 50, birdmesh.position.z);
    
                    renderer.clear();
                    renderer.render( scene, camera );
                }
        </script>
    
    </body>
    </html>
  • 相关阅读:
    DC(四)——笔试题
    验证&system verilog笔试题
    Centos和redhat6.0后关于虚拟机克隆后无法启用网卡问题
    搭建 CentOS 6 服务器(1)
    搭建 CentOS 6 服务器(16)
    搭建 CentOS 6 服务器(14)
    搭建 CentOS 6 服务器(15)
    搭建 CentOS 6 服务器
    搭建 CentOS 6 服务器(2)
    搭建 CentOS 6 服务器(3)
  • 原文地址:https://www.cnblogs.com/NuclearBoy/p/5675141.html
Copyright © 2020-2023  润新知