/filters/source/libs/dupin/particles/Emitter.as

https://github.com/wksaopaulo/WkBook · ActionScript · 161 lines · 119 code · 17 blank · 25 comment · 16 complexity · 22292a03b669db3e91663a29af591684 MD5 · raw file

  1. package dupin.particles
  2. {
  3. import flash.display.Sprite;
  4. import potato.core.IDisposable;
  5. import flash.events.Event;
  6. import flash.display.Bitmap;
  7. import potato.display.safeRemoveChild;
  8. import flash.display.BitmapData;
  9. import dupin.particles.motion.IParticleMotion;
  10. import dupin.particles.motion.PerlinMotion;
  11. import flash.geom.Rectangle;
  12. import flash.geom.Vector3D;
  13. import flash.display.DisplayObject;
  14. import flash.utils.setInterval;
  15. import flash.geom.Point;
  16. import dupin.display.drawRect;
  17. import flash.utils.clearInterval;
  18. /**
  19. * Particle emmiter
  20. * config keys:
  21. *
  22. * particleType:Class Class of the DisplayObject do emit
  23. * creationInterval:int Milis to wait before creating a new particle
  24. * maxParticles:int Maximum number of particles
  25. * motion:IParticleMotion Type of motion (Defaults to perlin)
  26. * bounds:Rectangle Bounds of the emitter (Defaults to: 500, 500)
  27. * beforeKill:Function Function called to execute custom code before particle destruction expected signature: beforeKill(particle:DisplayObject, callWhenDone:Functio):void
  28. *
  29. * @langversion ActionScript 3
  30. * @playerversion Flash 9.0.0
  31. *
  32. * @author Lucas Dupin
  33. * @since 08.03.2011
  34. */
  35. public class Emitter extends Sprite implements IDisposable
  36. {
  37. public static var RANDOM:String = "random";
  38. public static var BOTTOM:String = "bottom";
  39. //Config
  40. public var motion:IParticleMotion;
  41. protected var ParticleType:Class;
  42. protected var creationInterval:int;
  43. protected var maxParticles:int;
  44. protected var bounds:Rectangle;
  45. protected var beforeKill:Function;
  46. protected var initialPosition:String;
  47. // Internals
  48. private var _interval:int;
  49. protected var particles:Vector.<DisplayObject>;
  50. public function Emitter(config:Object=null)
  51. {
  52. config ||= {};
  53. //Setup
  54. ParticleType = config.particleType || DummyParticle;
  55. maxParticles = config.maxParticles || 50;
  56. creationInterval = config.creationInterval || 500;
  57. motion = config.motion || new PerlinMotion(maxParticles);
  58. bounds = config.bounds || new Rectangle(0, 0, 500, 500);
  59. beforeKill = config.beforeKill || _beforeKill;
  60. particles = new Vector.<DisplayObject>();
  61. initialPosition = config.initialPosition || BOTTOM;
  62. //Start emmiting
  63. addEventListener(Event.ENTER_FRAME, update, false, 0, true);
  64. //Create particles
  65. _interval = setInterval(createParticle, creationInterval);
  66. createParticle();
  67. }
  68. public function pause():void
  69. {
  70. removeEventListener(Event.ENTER_FRAME, update);
  71. }
  72. public function resume():void
  73. {
  74. addEventListener(Event.ENTER_FRAME, update, false, 0, true);
  75. }
  76. public function set boundsVisible(value:Boolean):void
  77. {
  78. if(value){
  79. with(graphics){beginFill(0xcc0000, 0.1), drawRect(bounds.x, bounds.y, bounds.width, bounds.height)};
  80. } else {
  81. graphics.clear();
  82. }
  83. }
  84. public function createParticle():void
  85. {
  86. if(particles.length >= maxParticles) return;
  87. //Create particle
  88. var p:DisplayObject = new ParticleType();
  89. addChild(p);
  90. //Positioning it
  91. if(initialPosition == BOTTOM){
  92. p.x = bounds.x + Math.random()*bounds.width;
  93. p.y = bounds.y + bounds.height - 1;
  94. } else if(initialPosition == RANDOM) {
  95. p.x = bounds.x + Math.random()*bounds.width;
  96. p.y = bounds.y + Math.random()*bounds.height;
  97. }
  98. particles.push(p);
  99. }
  100. public function update(e:Event):void
  101. {
  102. var pos:Vector3D;
  103. var p:DisplayObject;
  104. var i:Number=particles.length;
  105. while(--i > -1)
  106. {
  107. pos = motion.moveParticle(i);
  108. p = particles[i];
  109. p.x += pos.x;
  110. p.y += pos.y;
  111. p.z += pos.z;
  112. ////Kill?
  113. if(!bounds.containsPoint(new Point(p.x, p.y))){
  114. particles.splice(i, 1);
  115. tryToKill(p, i);
  116. }
  117. }
  118. motion.update();
  119. }
  120. public function tryToKill(p:DisplayObject, i:int):void
  121. {
  122. beforeKill(p, function():void{
  123. removeChild(p);
  124. })
  125. }
  126. public function dispose():void
  127. {
  128. removeEventListener(Event.ENTER_FRAME, update);
  129. clearInterval(_interval);
  130. }
  131. public function _beforeKill(p:DisplayObject, callback:Function):void
  132. {
  133. callback();
  134. }
  135. }
  136. }
  137. import flash.display.Shape;
  138. internal class DummyParticle extends Shape
  139. {
  140. public function DummyParticle()
  141. {
  142. with(graphics) beginFill(0xcc0000), drawCircle(0,0,10), endFill();
  143. }
  144. }