先把所有源码贴上然后在来解释。
package
{
import away3d.animators.ParticleAnimationSet;
import away3d.animators.ParticleAnimator;
import away3d.animators.data.ParticleProperties;
import away3d.animators.data.ParticlePropertiesMode;
import away3d.animators.nodes.ParticleBillboardNode;
import away3d.animators.nodes.ParticleColorNode;
import away3d.animators.nodes.ParticleFollowNode;
import away3d.animators.nodes.ParticleOscillatorNode;
import away3d.animators.nodes.ParticleVelocityNode;
import away3d.containers.View3D;
import away3d.controllers.HoverController;
import away3d.core.base.Geometry;
import away3d.core.base.Object3D;
import away3d.debug.AwayStats;
import away3d.debug.Trident;
import away3d.entities.Mesh;
import away3d.materials.ColorMaterial;
import away3d.primitives.PlaneGeometry;
import away3d.tools.helpers.ParticleGeometryHelper;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Vector3D;
public class Chuangjianyigelizishijie extends Sprite
{
private var view:View3D;
private var particle:ParticleAnimationSet;
//粒子控制器
private var particleAnimator:ParticleAnimator;
private var particleMesh:Mesh;
private var cameraController:HoverController;
private var vector3D:Vector.<Vector3D> = new Vector.<Vector3D>();
private var vector3Dm:Vector.<Vector3D> = new Vector.<Vector3D>();
private var followTarget1:Object3D;
private var particleFollowNode:ParticleFollowNode;
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
public function Chuangjianyigelizishijie()
{
initView();
initParticle();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseDown(event:MouseEvent):void
{
lastPanAngle = cameraController.panAngle;
lastTiltAngle =cameraController.tiltAngle;
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
move = true;
}
private function onMouseUp(event:MouseEvent):void
{
move = false;
}
private function initParticle():void{
var geometrySet:Vector.<Geometry> = new Vector.<Geometry>();
var plane:Geometry = new PlaneGeometry(10, 10, 1, 1, false);
for (var i:int = 0; i < 5000; i++)
{
geometrySet.push(plane);
var r:Number = Math.random()*1000;
var point:Vector3D = new Vector3D(Math.random()*r ,Math.random()*r ,0,5);
var pointm:Vector3D = new Vector3D(Math.random()*r ,Math.random()*r,Math.random()*r);
vector3D.push(point);
vector3Dm.push(pointm);
}
particle = new ParticleAnimationSet(true, true);
particle.addAnimation(new ParticleBillboardNode());
//其控制所述旋转的粒子总是面对相机
particle.addAnimation(new ParticleOscillatorNode(ParticlePropertiesMode.LOCAL_STATIC));
//起始坐标
particle.addAnimation(particleFollowNode = new ParticleFollowNode(true, false));
//粒子系统的后续行为
particle.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL, true, true, true, true, new ColorTransform(1, 1, 1, 1, 0x00, 0x00, 0x00), new ColorTransform(0.5, 0.5, 0.5, 1, 0xff)));
//改变粒子的颜色
followTarget1 = new Object3D();
particle.initParticleFunc = initParticleFunc;
var material:ColorMaterial = new ColorMaterial(0xffcc00);
particleAnimator = new ParticleAnimator(particle);
// 动画数据集,其中包含的粒子动画的动画师使用
particleMesh = new Mesh(ParticleGeometryHelper.generateGeometry(geometrySet), material);
//ParticleGeometryHelper.generateGeometry 一个辅助方法
particleMesh.animator = particleAnimator;
view.scene.addChild(particleMesh);
particleAnimator.start();
particleFollowNode.getAnimationState(particleAnimator).followTarget = followTarget1;
}
private function initParticleFunc(prop:ParticleProperties):void{
prop.startTime=Math.random()*10;
//粒子的起始时间
prop.duration = 2.5;
//粒子的寿命
prop[ParticleOscillatorNode.OSCILLATOR_VECTOR3D] = vector3D[prop.index];
//在一个单一粒子(当在本地地产模式)为振子的节点属性的参考。 预计Vector3D对象的轴(X,Y,Z)和周期上的粒子的运动速度(w)。
}
private function initView():void{
view = new View3D();
cameraController = new HoverController(view.camera, null, 0, 0, 1000);
addChild(new AwayStats(view));
var lix:Trident = new Trident(500,true);
view.scene.addChild(lix);
addChild(view);
}
private function onEnterFrame(event:Event):void
{
if (move) {
cameraController.panAngle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
cameraController.tiltAngle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
}
view.render();
followTarget1.x++;
}
}
}
这个就是效果图
我们直接从initParticle 函数说起。
var geometrySet:Vector.<Geometry> = new Vector.<Geometry>();
var plane:Geometry = new PlaneGeometry(10, 10, 1, 1, false);
for (var i:int = 0; i < 5000; i++)
{
geometrySet.push(plane);
var r:Number = Math.random()*1000;
var point:Vector3D = new Vector3D(Math.random()*r ,Math.random()*r ,0,5);
var pointm:Vector3D = new Vector3D(Math.random()*r ,Math.random()*r,Math.random()*r);
vector3D.push(point);
vector3Dm.push(pointm);
}
这段代码创建了5000个plane对象,其实就是5000个粒子。vector3d是粒子的初始坐标,
vector3dm是粒子的终点坐标。
值得注意的是vectpr3d有4个参数 ,这里第四个参数代表的是速度。
particle = new ParticleAnimationSet(true, true);
particle.addAnimation(new ParticleBillboardNode());
//其控制所述旋转的粒子总是面对相机
particle.addAnimation(new ParticleOscillatorNode(ParticlePropertiesMode.LOCAL_STATIC));
//控制粒子的位置,随着时间的推移,简谐运动
particle.addAnimation(particleFollowNode = new ParticleFollowNode(true, false));
//粒子系统的后续行为
particle.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL, true, true, true, true, new ColorTransform(1, 1, 1, 1, 0x00, 0x00, 0x00), new ColorTransform(0.5, 0.5, 0.5, 1, 0xff)));
//改变粒子的颜色
这一段 创建了一个粒子系统并给出了节点属性。
这里需要注意的是ParticlePropertiesMode的3个静态属性。
3个静态属性分别代表的意思是
ParticlePropertiesMode.GLOBAL=0
全局模式
ParticlePropertiesMode.LOCAL_DYNAMIC=2
局部动态模式
ParticlePropertiesMode.LOCAL_STATIC=1
本地静态属性
ParticleBillboardNode的节点作用
//其控制所述旋转的粒子总是面对相机
ParticleOscillatorNode
//控制粒子的初始位置,随着时间的推移,简谐运动
ParticleColorNode
//改变粒子的颜色
注意 ParticleColorNode 暂时只支持全局模式,也就意味着暂时没办法给单个粒子颜色。
ParticleFollowNode
//粒子系统的后续行为
其实就是用来控制整个粒子系统
其实还有很多节点属性,你只要去 away3d.animators.nodes 路径下就可以看到很多节点类
followTarget1 = new Object3D();
particle.initParticleFunc = initParticleFunc;
var material:ColorMaterial = new ColorMaterial(0xffcc00);
particleAnimator = new ParticleAnimator(particle);
// 动画数据集,其中包含的粒子动画的动画师使用
particleMesh = new Mesh(ParticleGeometryHelper.generateGeometry(geometrySet), material);
//ParticleGeometryHelper.generateGeometry 一个辅助方法
particleMesh.animator = particleAnimator;
view.scene.addChild(particleMesh);
particleAnimator.start();
particleFollowNode.getAnimationState(particleAnimator).followTarget = followTarget1;
这段需要注意的是particle.initParticleFunc = initParticleFunc;
initParticleFunc是用来写粒子运动轨迹的。
播放粒子系统的动画particleAnimator.start();还有一种方式
particleAnimator.update(毫秒数);
参数单位是毫秒。
private function initParticleFunc(prop:ParticleProperties):void{
prop.startTime=Math.random()*10;
//粒子的起始时间
prop.duration = 2.5;
//粒子的寿命
prop[ParticleOscillatorNode.OSCILLATOR_VECTOR3D] = vector3D[prop.index];
//在一个单一粒子(当在本地地产模式)为振子的节点属性的参考。 预计Vector3D对象的轴(X,Y,Z)和周期上的粒子的运动速度(w)。
}
重点来了initParticleFunc函数定义了粒子属性。
还记得刚刚所说的粒子系统的节点属性吗? 如果选择的是ParticlePropertiesMode.GLOBAL全局模式,
那当然不需要在initParticleFunc函数中进行属性定义,如果是选择的局部模式,那就需要在initParticleFunc
进行属性定义了。
至于属性怎么定义呢?很简单 我们每个使用的节点属性中都有一个或多个静态属性。我们使用
prop[静态属性]= 它需要的属性就OK了。
例
particle.addAnimation(new ParticleOscillatorNode(ParticlePropertiesMode.LOCAL_STATIC));
prop[ParticleOscillatorNode.OSCILLATOR_VECTOR3D] = vector3D[prop.index];
prop.index这个属性忠实的记录了当前操作到第几个粒子。
private function onEnterFrame(event:Event):void
{
if (move) {
cameraController.panAngle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
cameraController.tiltAngle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
}
view.render();
followTarget1.x++;
}
说了这么久还有那个节点属性ParticleFollowNode没有说到,用了ParticleFollowNode类之后我们就可以操作
粒子系统满世界乱跑,而且不会影响已经发射出去的粒子移动轨迹。