Threejs,小球沿随机线的轨迹运动

最近想做一个粒子沿轨迹线运动的东东,不过还是先实现了一个小目标,有空在添加粒子的部分。

功能:主要的功能如下,就是一个小球沿着一个随意生成的线运动。
在这里插入图片描述
原理:原理也不复杂,两个点之间的向量差就是小球应该运动的方向。直接加上小球当前的位置就是小球要到达的目标位置。

主要代码:默认为threeJS标准场景,参考:(留个坑,假装有连接)

先随机生成几个点存下来,我想让点都在坐标轴正方向的象限内,就取了随机数0-1的值,如果想让点存在于任意象限内,可以减去0.5

var points=[];
var pointsV3=[];
var point = new THREE.Vector3();
var direction = new THREE.Vector3();
for(var i =0; i < 8; i++)
{
  direction.x = Math.random();
  direction.y = Math.random();
  direction.z = Math.random();
  direction.normalize().multiplyScalar(30);

  point.add(direction);
  pointsV3.push(point.clone());
  points.push(point.x,point.y,point.z);
 }

根据随机点,生成一条线。用的是buffer格式的Geometry,所以,传进去的是一个float[]类型的数据,不是vector3[],这也是上面定义了 pointsV3 的原因, pointsV3 才是 vector3[] 类型的。

var lineGeometry = new THREE.BufferGeometry();
lineGeometry.addAttribute('position',new THREE.Float32BufferAttribute(points,3));
 var line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial({
 color:0x1e8cfc
 }));
 scene.add(line);

来一个小球,把小球的初始化位置放在第一个点的位置,这样方便观察它是不是老老实实的按照轨迹运行了。

material = new THREE.MeshStandardMaterial( {
					color: 0xfabbc1,
					metalness: 0.5,
					roughness: 1.0,
					flatShading: true
				} );
sphere = new THREE.Mesh( new THREE.SphereBufferGeometry( 3, 20, 20), material );
				sphere.position.set( 0, 0, 10 );
				sphere.name = "Sphere";
				scene.add( sphere );
sphere.position.set(pointsV3[0].x,pointsV3[0].y,pointsV3[0].z); 

目标位置:这里面的clone很重要,我说我怎么算都不对捏,查了three源码才知道,如果不clone的话,会污染掉position数据本身,他就会跑到其他我们不想要的位置上去。

tweenpos= sphere.position.clone().add(pointsV3[index+1].clone().sub(pointsV3[index]));

运动的动画,使用的是Tween.js,相关地址:https://github.com/tweenjs/tween.js

其实我们只需要一个 Tween.js 的脚本引入到我们的工程里就可以了。

主要的的运动代码如下:创建一个tween,传入起始位置,结束位置,运动方式,以及update和complete的回调。complete 的回调里重新计算了要移动的目标位置,并重新创建了一个动画。

tween = new TWEEN.Tween(sphere.position.clone())
                 .to(tweenpos,3000)
                 .easing(TWEEN.Easing.Quadratic.InOut)
                 .delay(1000)
                 .onUpdate(function(){sphere.position.set(this.x, this.y,this.z);})
                 .onComplete(tweenComplete)
                 .start();
function tweenComplete()
{  
  if((index+1)<pointsV3.length)
  {
     index++;
     tweenpos=sphere.position.clone().add(pointsV3[index+1].clone()
     .sub(pointsV3[index]));
     tween = new TWEEN.Tween(sphere.position.clone())
                      .to(tweenpos,3000)
                      .easing(TWEEN.Easing.Quadratic.InOut)
                      .delay(1000)
                      .onUpdate(function(){sphere.position.set(this.x,  this.y,this.z);})
                      .onComplete(tweenComplete)
                      .start();
  }
}
function animate(time) {
 TWEEN.update(time);
}

以上就是这个小测试的主要代码。来来,给自己挖个坑,我会尽快测试一下,粒子沿线移动的功能看看效果如何。详见:(假装这里有个链接 = =)点我~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值