Spray Paint

Here is an experiment trying to get near a spray paint effect.

The code is still untidy but never the less, here it is: ParticlePainter.zip


public class SprayPaint implements IPaint
    {
        private const NUM_PARTICLES_S: int = 500;
        private const NUM_PARTICLES_M: int = 3;
        private const NUM_PARTICLES_L: int = 1000;

        private const PI2: Number = Math.PI * 2;

        private var _canvas: BitmapData;
        private var _output: BitmapData;

        private var _radius: int;

        private var _particles: SprayParticle;

        private var _blur: BlurFilter = new BlurFilter( 1, 1, 3 );

        /**
         * Create a new SprayPaint object.
         */
        public function SprayPaint( canvas: BitmapData, radius: int = 50, color: uint = 0xAAAAAA )
        {
            _canvas = canvas;
            _radius = radius;

            var p: SprayParticle;

            p = _particles = new SprayParticle();

            var n: int = NUM_PARTICLES_L;

            while( --n > -1 )
            {
                p = p.next = new SprayParticleThick();
                p.color = color;
            }

            n = NUM_PARTICLES_M;

            while( --n > -1 )
            {
                p = p.next = new SprayParticleSplotch();
                p.color = color;
            }

            n = NUM_PARTICLES_S;

            while( --n > -1 )
            {
                p = p.next = new SprayParticleSpeckle();
                p.color = color;
            }
        }

        /**
         * @inheritDoc
         */
        public function paint( mouseX: int, mouseY: int, mouseDown: Boolean ): void
        {
            _output = new BitmapData( _canvas.width, _canvas.height, true, 0 );
            _output.lock();

            var temp: Number;

            var p: SprayParticle = _particles.next;

            do
            {
                --p.restLife;

                if( p.restLife < 0 )
                {
                    if( mouseDown )
                    {
                        temp = Math.random() * PI2;

                        p.distToOrigin = ( _radius * Math.random() ) / p.size;

                        p.x = mouseX + ( Math.sin( temp ) * p.distToOrigin );
                        p.y = mouseY + ( Math.cos( temp ) * p.distToOrigin );
                    }
                    else
                    {
                        p.x = -1;
                        p.y = -1;
                    }

                    p.restLife = p.lifespan;
                }
                else
                {
                    if( p.x != -1 && p.y != -1 )
                    {
                        p.y += p.restLife * p.viscosity;

                        p.alpha = 0xFF * ( 1 - ( p.distToOrigin / _radius ) );

                        p.paint( _output );
                    }
                }

                p = p.next;

            }
            while( p );

            _output.unlock();
            _output.applyFilter( _output, _output.rect, _output.rect.topLeft, _blur );
            _canvas.draw( _output );
            _output.dispose();
        }
    }