package { /** * @author nicoptere */ import flash.display.*; import flash.events.*; import flash.geom.*; public class VectorField extends MovieClip { public var vectors:Array; public var forceField:ForceField; public var forces:Array; public var pixels:BitmapData;//process Bitmap public var screen:BitmapData;//screen bitmap public var viewport:Bitmap; public var masque:Shape; public var W:Number; public var H:Number; public var isPressed:Boolean = false; public var OX:Number; public var OY:Number; //simulation static public var friction:Number = .999; static public var bounceType:String = 'loop'; //draws the emitters public var render:Boolean = true; public var drawForces:Boolean = true; public function VectorField( w:int = -1, h:int = -1 ) { W = w; H = h; forceField = new ForceField(); setup(); } public function setup():void { if( W != -1 && H != -1 ) { //creating the screen bitmaps pixels = new BitmapData( W, H, true, 0x00000000 ); screen = new BitmapData( W, H, true, 0x00000000 ); viewport = new Bitmap( screen, "always", true ); viewport.cacheAsBitmap = true; addChild( viewport ); masque = new Shape(); masque.graphics.beginFill(0xFFFFFF); masque.graphics.drawRect( 0, 0, W, H ); masque.cacheAsBitmap = true; addChild( masque ); this.mask = masque; } if( forceField.vectorField == null ) { forceField.setVectorField(this); } } public function init( nb:uint ):void { // bitmap setup if( screen == null )setup(); //creating the particles vectors = createVectors( nb ); } /* * creates the vectors Array * @param nb:uint the number of particles in the simulation. * */ public function createVectors( nb:uint = 256 ):Array { var vectors:Array = []; var x:Number; var y:Number; //used to create a hue cycle var nColorAngle:Number = 0; var nAngleInc:Number = Math.PI / 180; var R:Number; var G:Number; var B:Number; var col:uint = 0x0FFFFFFF; var radius:Number; var circle:Number; nAngleInc = Math.PI * 2 / nb; for( var i:int = 0; i < nb; i++ ) { //positionning // on a circle radius = W/4; circle = ( Math.PI * 2 ) / nb; x = W / 2 - Math.cos( i * circle ) * W / 8; y = H / 2 - Math.sin( i * circle ) * H / 8; //colors nColorAngle += nAngleInc; R = Math.cos( nColorAngle ) * 127 + 128 << 16; G = Math.cos( nColorAngle + 2 * Math.PI / 3) * 127 + 128 << 8; B = Math.cos( nColorAngle + 4 * Math.PI / 3) * 127 + 128; col = ( 255 << 24 | R | G | B ); //creates the vector var v:Vector = new Vector( x, y, 0, 0, col ); vectors.push( v ); } return vectors; } /* * update */ public function update( e:Event = null ):void { //check if there are forces to apply to the objects forces = forceField.forces; var FL:uint = forces.length; if( FL > 0 ) { //if so batch processes the vectors array for each ( var f:Force in forces ) { f.process( vectors ); } } if( render ) { //updates vectors positions var i:int; var v:Vector; var BL:uint = vectors.length; pixels.fillRect( pixels.rect, 0x000000 ); pixels.lock(); for ( i = 0; i < BL; i++) { //for each vector in simulation v = vectors[ i ]; pixels.setPixel32( v.x, v.y, v.color ); //boundaries check ( bounceType ) if( bounceType == 'loop' ) { //-> loop v.x = ( v.x < 0 ) ? W : ( v.x > W ) ? 0 :v.x; v.y = ( v.y < 0 ) ? H : ( v.y > H ) ? 0 :v.y; }else{ //->bounce on the sides of the screen v.vx = ( v.x < 0 ) ? -v.vx : ( v.x > W ) ? -v.vx :v.vx; v.vy = ( v.y < 0 ) ? -v.vy : ( v.y > H ) ? -v.vy :v.vy; } } } pixels.unlock(); //graphical output screen.draw( pixels ); } public function effect():void { //leaves a trail var a:Number = 1; var b:Number = .9; var ct:ColorTransform = new ColorTransform( a, a, a, b, 10, 10, 10, -10 ); screen.colorTransform(screen.rect, ct); } /* * force field getters/stters */ public function showForces():void { for each( var f:Force in forceField.forces ) { f.show(); } } public function hideForces():void { for each( var f:Force in forceField.forces ) { f.hide(); } } /* * reset vectors */ public function resetVectors():void { var BL:uint = vectors.length; for( var i:int = 0; i < BL; i++) { vectors[ i ] = null; } vectors = []; } /* * reset forces */ public function resetForces():void { //reste the forces forceField.reset(); } /* * resets all */ public function reset():void { resetVectors(); resetForces(); removeChild( viewport ); viewport = null; removeChild( masque ); masque = null; pixels.dispose(); screen.dispose(); } } }