Updated January 29, 2014, 4:42 pm

AS3 Smoke

This sample just renders a smoke sprite at the mouse cursor. Each particle is given slighly different velocity, opacity and size and then moved in almost the same direction.

The image used for the sprite is below.

Here is a demo app, moving the cursor around will move the particles starting location.

And here is the source code for the smoke class.

	
package  
{
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.net.URLRequest;
    
    public class Smoke extends Sprite
    {
        
        private var smokeBmp:Bitmap;
        
        private var canvas:Bitmap;
        
        private var particles:Vector.<Particle> = new Vector.<Particle>;
        
        private var maxParticleCount:int = 200;
        
        private var emitDelay:Number = 0.05;
        
        private var totalTime:Number = 0.0;
        
        public var emitPoint:Point = new Point();
        
        public function Smoke(filename:String) 
        {
            mouseEnabled = false;
            mouseChildren = false;
            
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSmokeImageLoaded);
            loader.load(new URLRequest(filename));
        }
        
        private function onSmokeImageLoaded(e:Event):void 
        {
            smokeBmp = e.target.content as Bitmap;
        }
        
        public function update(elapsedTime:Number):void 
        {
            if (!smokeBmp)
                return;
                
            totalTime += elapsedTime;
            
            if (totalTime > emitDelay && particles.length < maxParticleCount) 
            {
                emitParticle();
                totalTime -= emitDelay;
            }
            
            animateParticles(elapsedTime);
            
            sortParticles();
        }
            
        private function emitParticle():void 
        {
            var p:Particle = new Particle(smokeBmp.bitmapData);
            
            addChild(p);
            
            initParticle(p);
            
            particles.push(p);
        }
        
        private function initParticle(p:Particle):void 
        {
            p.x = emitPoint.x;
            p.y = emitPoint.y;
            p.velocity.x = Math.random() / 8;
            p.velocity.y = -(Math.random() + 0.4);
            p.velocity.normalize(1);
            
            p.scaleX = p.scaleY = Math.random() / 50 + 0.005;
            p.x -= p.width / 2;
            p.y -= p.height / 2;
            p.alpha = Math.random()/6.0 + 0.3;
            p.energy = p.alpha;
        }
        
        private function animateParticles(elapsedTime:Number):void 
        {
            var p:Particle;
            
            for (var i:int = 0; i < particles.length; i++) 
            {
                p = particles[i];
                p.x += p.velocity.x;
                p.y += p.velocity.y;
                
                p.energy -= elapsedTime * 0.05;
                p.alpha = p.energy;
                
                p.scaleX = p.scaleY = p.scaleX + 0.002;
                
                if (p.energy <= 0.0)
                    initParticle(p);
            }
        }
        
        private function sortParticles():void 
        {
            var p:Particle;
            
            particles.sort(compareFunction);

            for (var i:int = 0; i < particles.length; i++) 
            {
                p = particles[i];
                if(getChildIndex(p) != i)
                    setChildIndex(p, i);
            }
        }
        
        private function compareFunction(item1:Particle,item2:Particle):Number 
        {
            return item1.energy - item2.energy;
        }
    }

}