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