旋风(Whirlwind)

旋风(Whirlwind)

更多有趣示例 尽在小红砖社区

示例

在这里插入图片描述

CSS

body { margin: 0; background: #000; overflow:hidden;}
canvas { width: 100%; height: 100%; }

JS

var TWO_PI = Math.PI * 2;
var HALF_PI = Math.PI / 2;
var QUARTER_PI = Math.PI / 4;

var vLayers = 24; // complex: 100 / Small: 12 // Norm: 24
var tailResolution = 90; // segments in tail for full circumference
var maxTailLength = 0.5; //complex: 0.25 /  small: 0.5 // Norm: 0.33
var tailSegments = Math.round(tailResolution * maxTailLength);
var vMaxRadius = window.innerHeight/4;
var vHeight = window.innerHeight/3; 
var yOffset = -vHeight/2;
var maxPlotRadius = 5; // complex: 2 / small: 10 
var maxTailWeight = maxPlotRadius; // half plot diameter 
var linearRotationPerFrame = TWO_PI/600;

var maxAnimationLength = 20; // seconds
var animationProgress = 0;

var plotColor = 0xe1e1e1;
var plotOpacity = 1;

var tailColor = 0xe1e1e1;
var tailOpacity = 0.33;


var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 1000);

var renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var vSpheregeometry = new THREE.SphereGeometry( maxPlotRadius, 20, 20 );
var vSphereMaterial = new THREE.MeshBasicMaterial({color: plotColor});
var vTailMaterial = new THREE.MeshBasicMaterial( {color: tailColor, side: THREE.DoubleSide, wireframe: false, transparent: true, opacity: tailOpacity} );

var targetFrameRate = 30;

var vSpheres = [];
var vTails = [];
var initRotations = [];
var targetRotations = [];

init();


function init() {
  createVSpheres();
  createVTails();
}

function createVSpheres() {
  for ( var i = 0; i < vLayers; i++ ) {
    var sphereMesh = new THREE.Mesh( vSpheregeometry, vSphereMaterial );
    scene.add( sphereMesh );
    vSpheres[i] = sphereMesh;
    initRotations[i] = getRandom(0,1);
    targetRotations[i] = getRandom(0,1);
  }
}

function createVTails() {
  for ( var i = 0; i < vLayers; i++ ) {
    var vTailGeometry = new THREE.PlaneGeometry( 0,0,tailSegments,1 ); // arbitary w,h
    var tailMesh = new THREE.Mesh( vTailGeometry, vTailMaterial );
    scene.add( tailMesh );
    vTails[i] = tailMesh;
  }
}

function drawLayers() {

  for ( var l = 1; l <= vLayers; l++ ) {
    
    var layerAnimationTarget = targetRotations[l] * TWO_PI; // (value of property, like angle in radians) 
    var layerAnimationLength = maxAnimationLength; // (time) this could be randomised later
    var layerAnimationFrames = layerAnimationLength*targetFrameRate;
    var layerAnimationProgress = Math.min((animationProgress/layerAnimationFrames),1); 
    var layerAnimationProgressEased = GSAPEase(layerAnimationProgress);
    var layerAngleStart = initRotations[l] * TWO_PI + t*(linearRotationPerFrame*layerAnimationProgressEased);
    var layerAnimationNext = layerAngleStart + (layerAnimationProgressEased * layerAnimationTarget);
 
    tail(l, layerAnimationNext, layerAnimationProgressEased);
    plot(l, layerAnimationNext, layerAnimationProgressEased);
    
  }
  
}




function plot(layer, next, progress) {
  
  var plotCenterX = 0;
  var plotCenterY = 0;
  var plotCenterZ = 0;
  var layerScale = Math.tan((QUARTER_PI/vLayers)*layer);
  
  var layerRadius = vMaxRadius * layerScale;
  
  var nextX = plotCenterX+(layerRadius * Math.cos(next));
  var nextY = (yOffset + (vHeight/vLayers)*layer);  
  var nextZ = plotCenterZ+(layerRadius * Math.sin(next));
  
  var sphere = vSpheres[layer-1];
  var sphereScale = layerScale*progress;
  sphere.scale.set(sphereScale,sphereScale,sphereScale);
  sphere.position.set(nextX, nextY, nextZ);
  
  
}

function tail(layer, next, progress) {
  
  var plotCenterX = 0;
  var plotCenterY = 0;
  var plotCenterZ = 0;
  var layerScale = Math.tan((QUARTER_PI/vLayers)*layer);
  var layerRadius = vMaxRadius * layerScale;
  
  var radianIncrement = (TWO_PI*progress)/tailResolution;  
  //var tailLength = maxTailLength*progress;  
    
  var tail = vTails[layer-1];
  var tailVertexPairs = tail.geometry.vertices.length/2;
  
  for (v=tailVertexPairs-1; v >= 0; v--) {    
    
    var pProximity = 1-(Math.max(1,v)/tailVertexPairs);
    var tailWeight = (progress*(maxTailWeight*layerScale))*pProximity;
    
    var nextAngle = next - (v * radianIncrement);
    var nextX = plotCenterX+(layerRadius * Math.cos(nextAngle));
    var nextY = (yOffset + (vHeight/vLayers)*layer) + tailWeight/2;  
    var nextZ = plotCenterZ+(layerRadius * Math.sin(nextAngle));
    

    tail.geometry.vertices[v].x =  nextX;
    tail.geometry.vertices[v].y =  nextY;
    tail.geometry.vertices[v].z =  nextZ;  
    
    var oppositeV = v+tailVertexPairs;
    tail.geometry.vertices[oppositeV].x =  nextX;
    tail.geometry.vertices[oppositeV].y =  nextY-tailWeight;
    tail.geometry.vertices[oppositeV].z =  nextZ;
     
    tail.geometry.verticesNeedUpdate = true;
    
    }
  }











var t=0;

camera.position.z = 500;

var render = function () {
  requestAnimationFrame( render );
  animationProgress++;
  drawLayers();
  
  t++;
  animateCamera();
  renderer.render(scene, camera);
};

render();


window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}

var rotation = HALF_PI;
function animateCamera() {
  //console.log(rotation);
  //console.log(map_range(0.5, 0, 1, 200, 300));
  
  var camAnimationLength = maxAnimationLength; // could be adjusted later
  var camAnimationFrames = camAnimationLength*targetFrameRate;
  var camAnimationProgress = Math.min((animationProgress/camAnimationFrames),1); 
  var camAnimationProgressEased = GSAPEase(camAnimationProgress);
  
  var camInit = HALF_PI;
  var camTarget = 0.45;
  
  rotation = map_range(camAnimationProgressEased, 0, 1, camInit, camTarget)
  
  //rotation -= 0.0025;
  camera.position.x = 0;
  camera.position.y = Math.sin(rotation) * 500;
  camera.position.z = Math.cos(rotation) * 500;
  camera.lookAt( scene.position ); // the origin
}


 /*
 * This easing function converted from a great processing port of Robert Penner's easing functions:
 * Easing.pde (c) 2015 cocopon -> https://gist.github.com/cocopon/1ec025bcffb3fd7995db
 *
 * http://www.robertpenner.com/easing/
 * http://www.robertpenner.com/easing_terms_of_use.html
 */
function easeInOutQuart(t) {
  //test
  GSAPEase(t);
  
    t *= 2;
    if (t < 1) {
      return 0.5 * t * t * t * t;
    }
    t -= 2;
    return -0.5 * (t * t * t * t - 2);
}

/* alternative to above, the GSAP library */
function GSAPEase(t) {
  return Power4.easeInOut.getRatio(t);
  //return Expo.easeInOut.getRatio(t);
}

// input, input low, input high, target low, target high 
function map_range(value, low1, high1, low2, high2) { 
    return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
}




/* get random value frim range */
function getRandom(min, max) {
  return Math.random() * (max - min) + min;
}
展开阅读全文

Whirlwind

04-11
There is a very popular game named Zhen Sanguo Wushuang. My favorite character in this game is GuanYu, because of his powerful skill - whirlwind. As you can see in the picture, it's a terrible hurricane (you can treat it as a circle with radius of R) and anyone who stays in or on the boundary of it for T1 seconds will be dead. The duration of this skill will be T2 seconds. Besides there is a useful tool in this game called Tuimo Sword, when you use that, your enemy's speed will be slow down to half and the effect will lasts for T3 seconds. It's so powerful that you can only use it once, but you can decide when to use it. Assuming you are chasing your enemy now, and the distance between you and the enemy is D meters. You both move the same direction and you start to use your skill at the very beginning. Your speed is V1 meters per second and the enemy's speed is V2 meters per second. Give all the integers mentioned above, you must determined whether you can kill the enemy or not when the skill stopped. Note: if you reached the enemy, you just followed him and you can assume you are in the same position as him, but never pass through the enemy. Input The first line of the input is a integer T indicates the case number. In each case, there is one line containing 7 integers: D, R, T1, T2, T3, V1, V2, all the integer in the input will be in [1, 1000]. Output For each case, output yes if you can kill your enemy or no if you can't. Sample Input 4 1 2 1 1 1 2 1 36 24 10 13 2 6 4 12 24 45 100 25 4 6 36 24 10 100 24 4 6 Sample Output yes no no yes
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值