Away3D-2 简易火焰粒子系统
1 package 2 { 3 import away3d.tools.helpers.*; 4 import away3d.animators.data.*; 5 import away3d.animators.nodes.*; 6 import away3d.animators.*; 7 import away3d.materials.lightpickers.*; 8 import away3d.materials.methods.*; 9 import away3d.*; 10 import away3d.entities.*; 11 import away3d.materials.*; 12 import away3d.materials.methods.*; 13 import away3d.primitives.*; 14 import away3d.utils.*; 15 import away3d.containers.*; 16 import away3d.tools.commands.*; 17 import away3d.events.*; 18 import away3d.loaders.*; 19 import away3d.loaders.parsers.*; 20 import away3d.lights.*; 21 import away3d.core.base.*; 22 import away3d.cameras.*; 23 import away3d.controllers.*; 24 import away3d.primitives.*; 25 import away3d.tools.helpers.*; 26 27 import flash.display.*; 28 import flash.events.*; 29 import flash.ui.*; 30 import flash.display.*; 31 import flash.geom.*; 32 import flash.utils.*; 33 /** 34 * ... 35 * @author HonmaMeiko 36 */ 37 [SWF(width="600",height="400",backgroundColor="#FFFFFF", frameRate="60")] 38 public class Main extends Sprite 39 { 40 //粒子贴图 41 [Embed(source="blue.png")] 42 private static var blue:Class; 43 44 private var view:View3D; 45 public function Main() 46 { 47 view = new View3D(); 48 //粒子图形 49 var particle:Geometry = new PlaneGeometry(1, 1, 1, 1, false); 50 //粒子集合 51 var geometry:Vector.<Geometry> = new Vector.<Geometry>; 52 //创建含有10000个粒子的集合 53 for (var i:int = 0; i < 10000;++i) 54 { 55 geometry.push(particle); 56 } 57 58 //创建粒子动画属性集合 59 var animationSet:ParticleAnimationSet = new ParticleAnimationSet(true, true, true); 60 //添加广告板属性,使图形始终朝向camera 61 animationSet.addAnimation(new ParticleBillboardNode()); 62 //添加位置属性,设置节点的初始位置 63 animationSet.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0, 5, 0))); 64 //添加颜色属性,设置颜色初始和最终的材质变换矩阵 65 animationSet.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL,true,true,false,false,new ColorTransform(0, 0, 0, 1, 0xFF, 0x33, 0x01), new ColorTransform(0, 0, 0, 1, 0x99))); 66 //添加速度属性,设置粒子速度 67 animationSet.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.LOCAL_STATIC)); 68 //设置粒子初始化函数,用于设置每个粒子的属性 69 animationSet.initParticleFunc = InitParticle; 70 71 //创建粒子系统Mesh 72 var material:TextureMaterial = new TextureMaterial(Cast.bitmapTexture(blue)); 73 material.alphaBlending = true; 74 var particleMesh:Mesh = new Mesh(ParticleGeometryHelper.generateGeometry(geometry), material); 75 //创建粒子动画 76 var particleAnimator:ParticleAnimator = new ParticleAnimator(animationSet); 77 particleMesh.animator = particleAnimator; 78 //启动粒子动画 79 particleAnimator.start(); 80 particleMesh.x = 0; 81 particleMesh.y = -10; 82 particleMesh.z = 0; 83 84 view.scene.addChild(particleMesh); 85 view.camera.x = 100; 86 view.camera.y = 0; 87 view.camera.z = 0; 88 view.camera.lookAt(new Vector3D(0,0,0)); 89 90 91 //设置stage 92 stage.align = StageAlign.TOP_LEFT; 93 stage.scaleMode = StageScaleMode.NO_SCALE; 94 stage.addChild(view); 95 stage.addEventListener(Event.ENTER_FRAME, OnRender); 96 stage.addEventListener(Event.RESIZE, OnResize); 97 OnResize(); 98 } 99 private function InitParticle(prop:ParticleProperties):void 100 { 101 //设置粒子开始时间 102 prop.startTime = Math.random() * 20 - 20; 103 //设置粒子消失与再次出现之间的时间间隔 104 prop.delay = 0; 105 var z:Number = Math.random() * 10 - 4.9; 106 //设置粒子存活时间 107 prop.duration = Math.random() * 20 - Math.abs(z * 3); 108 109 //动画属性,设置粒子速度 110 prop[ParticleVelocityNode.VELOCITY_VECTOR3D] = new Vector3D(0,5,z); 111 } 112 private function OnResize(e:Event = null):void 113 { 114 view.width = stage.stageWidth; 115 view.height = stage.stageHeight; 116 } 117 private function OnRender(e:Event = null):void 118 { 119 120 view.render(); 121 } 122 } 123 }
创建粒子系统的步骤:
1.构造粒子图形集合
2.使用ParticleGeometryHelper.generateGeometry(geometry)把粒子集合生成为单一的Geometry,然后构造成Mesh.
3.构造粒子动画属性集合,使用addAnimation()设置动画属性,设置初始化函数.
属性的种类可参考文档的away3d.animators.nodes包.例如ParticleVelocityNode属性用于使粒子拥有速度属性,在ParticleVelocityNode的参数中可以设置ParticlePropertiesMode.LOCAL_STATIC和ParticlePropertiesMode.GLOBAL以及ParticlePropertiesMode.LOCAL_DYNAMIC三种,由于第三种相对消耗性能,因此通常使用前两种.ParticlePropertiesMode.LOCAL_STATIC表示每个粒子都可以独立设置该属性(在粒子初始化函数中设置),ParticlePropertiesMode.GLOBAL则表示所有粒子使用一样的属性值,在创建属性的时候设置.如ParticlePositionNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0, 5, 0))则表示所有粒子都有一样的起始位置(0,5,0).而ParticleVelocityNode(ParticlePropertiesMode.LOCAL_STATIC))则需要单独为每个粒子设置速度属性.
在初始化函数中,主要设置三项属性:
prop.startTime:粒子起始时间
prop.duration:粒子存活时间
prop.delay:粒子死亡后到重新出现的时间间隔.
如果在动画设置的属性中有需要为每个粒子设置的属性,则需要通过prop[ParticleVelocityNode.VELOCITY_VECTOR3D]这样的方式来访问设置该属性,这里需要为每个粒子设置速度属性(速度属性设置了ParticlePropertiesMode.LOCAL_STATIC).
4.生成粒子动画:var particleAnimator:ParticleAnimator = new ParticleAnimator(animationSet);创建粒子动画需要将粒子动画属性集合作为参数传递进去.
5.设置粒子网格的动画属性:particleMesh.animator = particleAnimator;
6.启动粒子动画:particleAnimator.start();
其中1,2步与3,4步之间并没有直接的顺序关系,因此只需要在第5步之前做好就行了.
火焰粒子效果简易算法:
prop.startTime = Math.random() * 20 - 20;随机函数产生0到1的值,因此所有粒子的开始时间都会在-10到0之间.
prop.delay = 0;表示粒子存活时间结束之后立即重新从初始位置产生该粒子,
我们的camera设置在(100,0,0)处,因此我们要让粒子在YZ平面上运动.
var z:Number = Math.random() * 10 - 4.9;随机产生该粒子的Z方向速度.Z方向的速度也可以认为是最终希望粒子到达的Z坐标,Z坐标最大值是5.1.
prop.duration = Math.random() * 20 - Math.abs(z * 3);随机产生粒子的存活时间,粒子|Z|越大,存活时间越短
prop[ParticleVelocityNode.VELOCITY_VECTOR3D] = new Vector3D(0,5,z);设置粒子的速度.