ThreeJS-世界杯点球小游戏(三十三)

素材:

链接: https://pan.baidu.com/s/1Ee63QRLEW4XSXUIZPjKLRw

提取码: agxh 

新组件:

npm install cannon-es -S

新引入:

 import * as CANNON from "cannon-es";

关键代码:

 const gltfLoader = new GLTFLoader().setPath("three/glb/");

    const dracoLoader = new DRACOLoader()

      .setDecoderPath("three/draco/")

      .setDecoderConfig({ type: "js" });

    gltfLoader.setDRACOLoader(dracoLoader);

    let ball, ballBody;

    gltfLoader.load("playground02.glb", (gltf) => {

      //开启建模物体的阴影和接收阴影的功能

      const mode = gltf.scene;

      mode.traverse((child) => {

        console.log(child.name, child.name.search(/^Solid.*$/) == -1);

        if (child.isMesh) {

          child.castShadow = true;

          child.receiveShadow = true;

        }

        if (child.name == "Soccer_Ball") {

          ball = child;

          //创建一个物理世界物体,半径0.15

          const ballShape = new CANNON.Sphere(0.15);

          ballBody = new CANNON.Body({

            mass: 1, //1kg

            position: new CANNON.Vec3(0, 3, 0),

            shape: ballShape,

          });

          world.addBody(ballBody);

        }

        if (child.isMesh && child.name.search(/^Solid.*$/) == -1) {

          //创建trimesh类

          const trimesh = new CANNON.Trimesh(

            child.geometry.attributes.position.array,

            child.geometry.index.array

          );

          //创建物体

          const trimeshBody = new CANNON.Body({

            mass: 0,

            shape: trimesh,

          });

          //getWorldPosition是绝对定位(相对于世界),position是相对定位(如果有组相对于组,没有组相对于世界)

          trimeshBody.position.copy(

            child.getWorldPosition(new THREE.Vector3())

          );

          trimeshBody.quaternion.copy(

            child.getWorldQuaternion(new THREE.Quaternion())

          );

          world.addBody(trimeshBody);

        }

      });

      setTimeout(() => {

        ballBody.position.set(0, 3, 0);

        ballBody.velocity.set(0, 0, 0);//速度

        ballBody.angularVelocity.set(0, 0, 0);

      }, 2000);

      scene.add(mode);

    });

 

  let renderFun = () => {

      world.step(clock.getDelta());

      if (ball && ballBody) {

        //更新积分器的计算步长

        ball.position.copy(ballBody.position);

        ball.quaternion.copy(ballBody.quaternion);

      }

      //更新阻尼数据

      controls.update();

      //需要重新绘制canvas画布

      render.render(scene, camera);

      //监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数

      //但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果

      window.requestAnimationFrame(renderFun);

    };

    // window.requestAnimationFrame(renderFun);

    renderFun();

效果图:

 

 

你可能感兴趣的:(前端,javascript,html)