/** * * Sample code for FITC * Basic 40000 particle. * What is interesting is that, actually this one is 4 times more amount of particles than that of smokey one. * However people feel this one use less particle. * */ package { import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.events.Event; import flash.filters.BlurFilter; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.utils.ByteArray; public class FlashTest extends Sprite { //View protected var canvas:BitmapData; protected var canvasBitmap:Bitmap; //BitmapData that contains the actual froce that is applied to particles. protected var forceMap:BitmapData; //BitmapData that contains the force of the storm. protected var stormMap0:BitmapData; protected var stormMap1:BitmapData; //BitmapData that contains the mouse repulsion force of the stage. protected var repulsionMap:BitmapData; protected var repulsionHistoryMap:BitmapData; protected var repulsionFadeMap:BitmapData; //the number of particles. 5000-200000 protected var particleNum:int = 40000; protected var particles:Vector. // protected var stormScaleRatioX:Number; protected var stormScaleRatioY:Number; protected var stormCycle:Number = 0; //color transform that guradually changes canvas. protected var fadeCanvasColt:ColorTransform; protected var canvasBlurFilter:BlurFilter; //temporaly variables protected var tempColt:ColorTransform = new ColorTransform(); protected var tempPt:Point = new Point(); protected var tempMat:Matrix = new Matrix(); public function FlashTest() { init(); reset(); } protected function init():void { //build View canvasBitmap = new Bitmap(null, "auto", false); addChild(canvasBitmap); //initialize the map that contains force of the storm; stormMap0 = new BitmapData(256,256,false,0x000000); stormMap0.perlinNoise(128,128,3,Math.random()*100,false,true,3,false); stormMap1 = new BitmapData(256,256,false,0x000000); stormMap1.perlinNoise(128,128,3,Math.random()*100,false,true,3,false); // forceMap = new BitmapData(256,256,false,0x000000); //initialize repulsionMap repulsionHistoryMap = new BitmapData(256,256,false,0x000000); repulsionFadeMap = new BitmapData(256,256,true,0x20808000); repulsionMap = new BitmapData(256,256,false,0); /** * First we preculculate the repulsion force field that mouse cursor generates as a bitmapdata. * Red channel of bitmap data contains horizontal force. * Green channel of bitmap data contains vertical force. */ var dx:int, dy:int; var dist:Number, fx:Number, fy:Number; var col:int; for(var yy:int=0; yy<256; yy++) { for(var xx:int=0; xx<256; xx++){ dx = xx-128; dy = yy-128; dist = Math.sqrt(dx*dx+dy*dy); if(dist<1){ fx = 0; fy = 0; }else{ fx = dx / dist / dist / dist * 10000; fy = dy / dist / dist / dist * 10000; } fx = (fx<-128)? -128 : (fx>127)? 127 : fx; fy = (fy<-128)? -128 : (fy>127)? 127 : fy; fx += 128; fy += 128; col = (fx<<16) + (fy<<8) repulsionMap.setPixel(xx,yy,col); } } //You can see canvasBitmap.bitmapData = repulsionMap; //initialize particle particles = new Vector.(particleNum); var particle:Particle; var rr:int; for(var i:int=0; i loopW){ prt.x = 1; } if(prt.y<0){ prt.y = loopH; }else if(prt.y > loopH){ prt.y = 1; } //Self implimentation of addtive color blend mode. //Because there is too many particle, blending particle with low brightness color is much effective. col = canvas.getPixel(int(prt.x), int(prt.y)); r = (col>>16&0xff) + prt.r; g = (col>>8&0xff) + prt.g; b = (col&0xff) + prt.b; r = (r<0xff)? r : 0xff; g = (g<0xff)? g : 0xff; b = (b<0xff)? b : 0xff; canvas.setPixel(int(prt.x), int(prt.y), (r<<16)|(g<<8)|b); } //canvas.applyFilter(canvas, canvas.rect, tempPt, canvasBlurFilter); canvas.unlock(); } } } class Particle { //particle position public var x:Number = 0; public var y:Number = 0; public var vx:Number = 0; public var vy:Number = 0; //particle color public var r:int; public var g:int; public var b:int; //scale factor that affects the force applied to the particle. public var scaleFactor:Number; }