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);设置粒子的速度.

 

posted @ 2013-05-01 12:00  Kinel  阅读(707)  评论(1)    收藏  举报