three+simplex-noise实现飞机在山林飞行动画效果代码

代码语言:html

所属分类:动画

代码描述:three+simplex-noise实现飞机在山林飞行动画效果代码

代码标签: three simplex-noise 飞机 山林 飞行 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
<style>
    html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: radial-gradient(120vw 50vh, #4c0c30 30%, #c90997);
}

.scene {
  height: 100vh;
  display: flex;
  align-items: flex-end;
}
.scene > div {
  width: 100%;
}

canvas {
  vertical-align: bottom;
}
</style>

</head>

<body>
    <!-- partial:index.partial.html -->
    <div class="scene">
        <div data-module="world">
        </div>
    </div>
    <!-- partial -->
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.108.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/simplex-noise.min.js"></script>
    <script >
        const simplex = new SimplexNoise(Math.random());

const MAP_SIZE = 100;
const SPEED_DEFAULT = 0.01;

const PI = Math.PI;
const TAU = PI / 2;

const BUMPER_X_SPACING = 2;
const BUMPER_Z_SPACING = 2;

class Generator {
  constructor() {
    this.cellSize = 1;

    const width = MAP_SIZE;
    const height = MAP_SIZE;

    this.cols = Math.ceil(width / this.cellSize);
    this.rows = Math.ceil(height / this.cellSize);

    this.phase = 0;
    this.phaseX = 0;
    this.phaseY = 0;

    this.speed = 0.05;
    this.scale = 0.01;
  }

  setOptions(options = {}) {
    Object.keys(options).forEach(option => {
      if (this[option]) {
        this[option] = options[option];
      }
    });
  }

  update(angle = 0, speedModifier = 0) {
    const speed = SPEED_DEFAULT + speedModifier;
    const numLoops = this.rows * this.cols;

    let x = 0;
    let y = 0;

    const values = [];

    for (let i = 0; i < numLoops; i++) {
      const noiseX = x * this.scale;
      const noiseY = y * this.scale;

      const noiseValue = simplex.noise2D(noiseX - this.phaseX, noiseY - this.phaseY);

      x += this.cellSize;

      if (i > 0 && i % this.cols === 0) {
        y += this.cellSize;
        x = 0;
      }

      values.push(noiseValue);
    }

    this.phase += speed;

    this.phaseX += Math.cos(angle) * speed;
    this.phaseY += Math.sin(angle) * speed;

    return values;
  }}



class Ship {
  constructor() {
    this.speedInc = 0;

    this.raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0));

    // containing ship
    this.model = new THREE.Object3D();

    // containing side bumpers
    this.bumpers = new THREE.Object3D();

    // containing ship and bumpers
    this.container = new THREE.Object3D();

    // model containing ship, constructed upwards. So rotate it 90deg
    this.model.rotation.x = -TAU;

    this.container.add(this.model);
    this.container.add(this.bumpers);

    this.createModel(this.model);
    this.createBumpers(this.bumpers);
  }

  createModel(container) {
    const shipBodyradius = 1;
    const noseLength = 2;
    const bodyLength = 5;
    const exaustLength = 1;

    const totalLength = noseLength + bodyLength + exaustLength;
    const halfLength = totalLength / 2;

    const noseMat = new THREE.MeshPhongMaterial({ color: 0xffffff });
    const noseGeom = new THREE.CylinderGeometry(0, shipBodyradius, noseLength, 10, 10, false);
    const nose = new THREE.Mesh(noseGeom, noseMat);
    nose.position.y = halfLength - noseLength / 2;
    container.add(nose);

    const bodyMat = noseMat;
    const bodyGeom = new THREE.CylinderGeometry(shipBodyradius, shipBodyradius, bodyLength, 10, 10, false);
    const body = new THREE.Mesh(bodyGeom, bodyMat);
    body.position.y = halfLength - noseLength - bodyLength / 2;
    container.add(body);

    const exaustMaterial = new THREE.MeshPhongMaterial({ color: 0xbbbbbb, side: THREE.DoubleSide });
    const exaustGeom = new THREE.CylinderGeometry(shipBodyradius, 0.5, exaustLength, 10, 5, true);
    const exaust = new THREE.Mesh(exaustGeom, exaustMaterial);
    exaust.position.y = halfLength - noseLength - bodyLength - exaustLength / 2;
    container.add(exaust);

    const wingWidth = 3;
    const wingHeight = 2;
    const wingShape = new THREE.Shape();

    wingShape.moveTo(0, 0);
    wingShape.lineTo(wingWidth, -wingHeight - 0.5);
    wingShape.lineTo(wingWidth, -wingHeight - 1);
    wingShape.lineTo(0, -wingHeight);
    wingShape.lineTo(0, 0);

    const extrudeSettings = {
      steps: 2,
      depth: 0.25,
      bevelEnabled: true,
      bevelThickness: 0.1,
      bevelSize: 1,
      bevelSegments: 1 };


    const wingGeom = new THREE.ExtrudeGeometry(wingShape, extrudeSettings);
    const wingMat = noseMat;
    const wingRight = new THREE.Mesh(wingGeom, wingMat);
    wingRight.position.y = 1;
    container.add(wingRight);

    const wingLeft = wingRight.clone();
    wingLeft.material = wingMat;
    wingLeft.rotation.y = PI;
    wingLeft.position.z = 0.25;
    container.add(wingLeft);

    const tailScale = 0.4;
    const tailAmp = PI / 10;

    const tailRight = wingRight.clone();
    tailRight.material = wingMat;
    tailRight.scale.set(tailScale, tailScale, tailScale);
    tailRight.rotation.y = -TAU + tailAmp;
    tailRight.position.y = -(bodyLength / 3.5);
    container.add(tailRight);

    const tailLeft = wingRight.clone();
    tailLeft.material = wingMat;
    tailLeft.scale.set(tailScale, tailScale, tailScale);
    tailLeft.rotation.y = -TAU - tailAmp;
    tailLeft.position.y = -(bodyLength / 3.5);
    container.add(tailLeft);

    return container;
  }

  createBumpers(container) {
    const bumperVisible = false;

    const bumperGeometry = new THREE.CylinderGeometry(0.1, 0.1, 100, 20);
    const bumperMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00, opacity: 0.1 });

    this.bumperFront = new THREE.Mesh(bumperGeometry, bumperMaterial);
    this.bumperFront.position.set(0, 25, -BUMPER_Z_SPACING);
    this.bumperFront.visible = bumperVisible;

    this.bumperBack = new THREE.Mesh(bumperGeometry, bumperMaterial);
    this.bumperBack.position.set(0, 25, BUMPER_Z_SPACING);
    this.........完整代码请登录后点击上方下载按钮下载查看

网友评论0