code on 2008-12-31
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
[SWF( width="484", height="490", frameRate="25" , backgroundColor="0x000000")]
public class Plasma
extends Sprite
{
protected const w : int = 484;
protected const h : int = 490;
protected var bd : BitmapData;
protected var ba : ByteArray;
protected var position : uint;
protected var p : Point;
protected var rect : Rectangle;
protected var shifter : int;
protected var blur : BlurFilter;
protected const A : Vector.<int> = new Vector.<int>( 256, true );
protected const R : Vector.<int> = new Vector.<int>( 256, true );
protected const G : Vector.<int> = new Vector.<int>( 256, true );
protected var plasma : Vector.<int>;
public function Plasma()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.LOW;
ba = new ByteArray();
p = new Point(0, 0);
rect = new Rectangle( 0, 0, w, h );
bd = new BitmapData( w, h, true, 0 );
blur = new BlurFilter( 4, 4, 1 );
addChild( new Bitmap( bd ) );
// generate palette
var i : int = 256;
while( --i > - 1 )
{
A[i] = int(128 + 128 * Math.sin( 3.1415 * i / 32));
R[i] = int(128 + 128 * Math.sin( 3.1415 * i / 16));
G[i] = int(128 + 128 * Math.sin( 3.1415 * i / 64));
}
// generate plasma
var x : int, y : int, l : int = w*h, b : Boolean = true;
plasma = new Vector.<int>( l, false );
while( --l > - 1 )
{
x = l % w;
y = (l - x) / w;
var color : Number;
if ( b )
color = (128+(128*Math.sin(x/128))+128+(128*Math.sin(y/128)))/2;
else
color = (128+(128*Math.sin(x/16))+128+(128*Math.sin(y/8))+128+(128*Math.sin((x+y)/16))+128+(128*Math.sin(Math.sqrt(x*x+y*y)/8)))/4;
plasma[l] = color;
b = !b;
}
// init screen
for( x = 0; x < w; x++ )
{
for( y = 0; y < h; y++ )
{
var pos : Number = (x+(y*w))*4;
ba[pos] = 255;
ba[pos+1] = 0;
ba[pos+2] = 0;
ba[pos+3] = 0;
}
}
addEventListener( Event.ENTER_FRAME, enterFrame );
}
protected function enterFrame( e : Event ) : void
{
bd.lock();
var t : int = ++shifter, pos : int = w*h, palID : int, ID : int;
while ( --pos > - 1 )
{
palID = int((plasma[pos] + t) % 255);
ID = int(pos << 2); // to process ARGB channels, same as pos *= 4;
ba[ID] = A[palID];
ba[ID+1]= R[palID];
ba[ID+2]= G[palID];
}
ba.position = 0;
bd.setPixels( rect, ba );
bd.applyFilter( bd, bd.rect, p, blur );
bd.unlock();
}
}
}