In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Particle Painter

Get Adobe Flash player
by leichtgewicht 16 May 2010
/**
 * Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rlp2
 */

package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    
    public class Drawing extends Sprite {
    	
    		internal static const AMOUNT_PARTICLES: int = 20;    		
    		internal static const ANGLE_PER_PARTICLE: Number = 2 * Math.PI / AMOUNT_PARTICLES;
    		internal static const PARTICLE_POWER_DECAY: Number = 0.7;
    		internal static const PARTICLE_POWER_MIN_LIMIT: Number = 0.0001;
    		internal static const COLOR_PER_DRAW: Number = 0x08;
    		internal static const DISTANCE_LIMIT: Number = 4;
    		
    		private var _bitmap: Bitmap;
    		private var _bitmapAsVector: Vector.<uint>;
    		private var _width: Number;
    		private var _height: Number;
    		private var _fullRect: Rectangle;
    		private var _out: TextField;
    		private var _down: Boolean;
    		private var _formerX: Number;
    		private var _formerY: Number;
    		private const _particleList: ParticleList = new ParticleList();
    	
        public function Drawing() {
        		addEventListener( Event.ENTER_FRAME, drawParticles );
        		stage.addEventListener( MouseEvent.MOUSE_DOWN, startDraw );
        		stage.addEventListener( MouseEvent.MOUSE_UP, stopDraw );
        		
        		_height = stage.stageWidth;
        		_width = stage.stageHeight;
        		_formerX = mouseX;
        		_formerY = mouseY;
        		stage.frameRate = 60;
        			
        		addChild( _bitmap = new Bitmap( new BitmapData(_width, _height, false ) ) );
        		_out = new TextField();
        		_out.height = stage.stageHeight;
        		_out.width = stage.stageWidth;
        		
        		_fullRect = new Rectangle( 0, 0, _width, _height );
        		
        		_bitmapAsVector = _bitmap.bitmapData.getVector( _fullRect );
        		
        		
        		for( var x: int = 0; x < _width; ++x )
        		{
        			for( var y: int = 0, yReal: int = 0; y < _height; ++y, yReal += _width )
        			{
        				_bitmapAsVector[ yReal + x ] = 0xFFFFFF;
        			}
        		}
        }
        
        private function startDraw( event: MouseEvent ): void {
        		_down = true;
        	}
        	
        	private function stopDraw( event: MouseEvent ): void {
        		_down = false;
        	}
        
        private function sendParticles(): void {
        		var xStep: Number = (mouseX-_formerX) / AMOUNT_PARTICLES;
        		var yStep: Number = (mouseY-_formerY) / AMOUNT_PARTICLES;
        		for( var i: int = 0, x: Number = _formerX, y: Number = _formerY; i< AMOUNT_PARTICLES; ++i, y+=yStep, x+=xStep ) {
        			var particle: Particle = Particle.getOrCreate();
        			particle.x = x;
        			particle.y = y;
        			particle.power = 1.0;
        			particle.directionX = Math.random();
        			particle.directionY = Math.random();
        			
        			particle.partRight = 1.0;//particle.directionX < 0.0 ? -particle.directionX : 0.0;
        			particle.partLeft = 1.0;//particle.directionX > 0.0 ? particle.directionX : 0.0;
        			particle.partBottom = 1.0;//particle.directionY < 0.0 ? -particle.directionY : 0.0;
        			particle.partTop = 1.0;//particle.directionY > 0.0 ? particle.directionY : 0.0;
        			
        			particle.partTopLeft = particle.partTop * particle.partLeft;
        			particle.partTopRight = particle.partTop * particle.partRight;
        			particle.partBottomLeft = particle.partBottom * particle.partLeft;
        			particle.partBottomRight = particle.partBottom * particle.partRight;
        			
        			//_out.appendText( "\nNew particle: " + particle.directionX + ":" + particle.directionY + ":" + particle.x + ":" + particle.y + ":" + particle.speed ) ;
        			_particleList.add( particle );
    			}
        	}
        	
        	private function drawParticles( event: Event = null ): void {
        		
        		if( _down ) //&& Math.abs(mouseX - _formerX) + Math.abs( mouseY - _formerY ) < DISTANCE_LIMIT )
        		{
        			sendParticles();
        		}
        		
        		_formerX = mouseX;
        		_formerY = mouseY;
        		var current: ParticleListNode = _particleList.first;
        		
        		while( current ) {
        			_particleList.next = current.next;
        			var particle: Particle = current.particle;
        			var draw: Number = particle.power;
        			
        			var x: int = int( particle.x );
        			var xValue: Number = particle.x - x;
        			var y: int = int( particle.y );
        			var yBase: int = y * _width;
        			var yValue: Number = particle.y - y;
        			
        			particle.x += particle.directionX * particle.power;
        			particle.y += particle.directionY * particle.power;
        			
        			if( x > 0 && y > 0 && x < _width-1 && y < _height-1 )
        			{
        			
	        			var p1: uint = yBase + x;
	        			var p2: uint = yBase + x + 1;
	        			var p3: uint = yBase + _width + x;
	        			var p4: uint = yBase + _width + x + 1;
	        			var vx: Number = ( 0x3fc - ( _bitmapAsVector[p1] & 0xFF ) * particle.partTopLeft + ( _bitmapAsVector[p2] & 0xFF ) * particle.partTopRight + ( _bitmapAsVector[p3] & 0xFF ) * particle.partBottomLeft + ( _bitmapAsVector[p4] & 0xFF ) * particle.partBottomRight ) / 0x3fc;
	        			
	        			//_out.appendText( "\n"+ vx );
	        			
	        			particle.power += vx * 0.001;
	        			
	        			var cBase: Number = COLOR_PER_DRAW * particle.power;
	        				        			
	        			var a1: int = ( xValue + yValue ) * cBase;
	        			var a2: int = ( xValue + (1.0-yValue) ) * cBase;
	        			var a3: int = ( (1.0-xValue) + yValue ) * cBase;
	        			var a4: int = ( (1.0-xValue) + (1.0-yValue) ) * cBase ;
	        			
	        			//_out.appendText( "\n"+xValue+","+yValue );
	        			
	        			a1 = a1 | a1 << 8 | a1 << 16;
	        			a2 = a2 | a2 << 8 | a2 << 16;
	        			a3 = a3 | a3 << 8 | a3 << 16;
	        			a4 = a4 | a4 << 8 | a4 << 16;
	        			
	        			
        				var c1n: int = _bitmapAsVector[ p1 ] - a1;
        				_bitmapAsVector[ p1 ] = c1n > 0 ? c1n : 0;
        				
        				var c2n: int = _bitmapAsVector[ p2 ] - a2;
        				_bitmapAsVector[ p2 ] = c2n > 0 ? c2n : 0;
        				
        				var c3n: int = _bitmapAsVector[ p3 ] - a3;
        				_bitmapAsVector[ p3 ] = c3n > 0 ? c3n : 0;
        				
        				var c4n: int = _bitmapAsVector[ p4 ] - a4;
        				_bitmapAsVector[ p4 ] = c4n > 0 ? c4n : 0;
        			}
        			particle.power *= PARTICLE_POWER_DECAY;
        			
        			if( particle.power <= PARTICLE_POWER_MIN_LIMIT ) {
        				_particleList.remove( current );
        				Particle.dispose( particle );
        			}
        			current = _particleList.next;
        		}
        		_bitmap.bitmapData.setVector( _fullRect, _bitmapAsVector );
        	}
    }
}

import flash.utils.Dictionary;

class ParticleList {
	internal var first: ParticleListNode;
	internal var next: ParticleListNode;
	internal var last: ParticleListNode;
	
	internal function add( particle: Particle ): void {
		var node: ParticleListNode = ParticleListNode.getOrCreate();
		node.particle = particle;
		if( !first )
		{
			first = node;
		}
		else
		{
			last.next = node;
			node.prev = last;
		}
		if( !next ) {
			next = node;
		}
		last = node;
	}
	
	internal function remove( node: ParticleListNode ): void {
		
		if(  node == first ) {
			first = node.next;
		} else {			
			node.prev.next = node.next;
		}
		
		if( node == last ) {
			last = node.prev;
		} else {
			node.next.prev = node.prev;
		}
		
		if( node == next ) {
			next = node.next;
		}
		ParticleListNode.dispose( node );
	}
}

class ParticleListNode {
	
	private static var _pool: Vector.<ParticleListNode> = new Vector.<ParticleListNode>();
	
	internal static function getOrCreate(): ParticleListNode {
		if( _pool.length > 0 )
		{
			return _pool.pop();
		}
		return new ParticleListNode();
	}
	
	internal static function dispose( node: ParticleListNode ): void {
		_pool.push( node );
		node.next = null;
		node.prev = null;
		node.particle = null;
	}
	
	internal var next: ParticleListNode;
	internal var prev: ParticleListNode;
	internal var particle: Particle;
}

class Particle {
	
	private static var _particles: Vector.<Particle> = new Vector.<Particle>();
	
	internal static function getOrCreate(): Particle {
		if( _particles.length > 0 )
		{
			return _particles.pop();
		}
		return new Particle();
	}
	
	internal static function dispose( particle: Particle ): void {
		_particles.push( particle );
	}
	
	internal var x: Number;
	internal var y: Number;
	internal var power: Number;
	internal var directionX: Number;
	internal var directionY: Number;
	
	internal var partLeft: Number;
	internal var partRight: Number
	internal var partTop: Number;
	internal var partBottom: Number;
	
	internal var partTopLeft: Number;
	internal var partTopRight: Number
	internal var partBottomLeft: Number;
	internal var partBottomRight: Number
}