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

life of Microorganism

Dropwaterデバッグ中にできたエフェクトから派生。あいかわらずむちゃくちゃ重いです。もともとは生態シミュレータ的なものに
したかったんですが、いまいちなので寝かせていました。Dropwaterを無理無理改造しているのでソースは汚いです。

曲はAlainMikuni氏(from gainaさんのsoundtest11 http://wonderfl.net/c/bB5h)からお借りしています。
ありがとうございます。

※操作できません。微生物?の動きを眺めてください

2010/9/28 微調整
2010/9/29 さらに微調整。顕微鏡感を増してみた
/**
 * Copyright zendenmushi ( http://wonderfl.net/user/zendenmushi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oUra
 */

//  << life of Microorganism >> 
//
// Dropwaterデバッグ中にできたエフェクトから派生。あいかわらずむちゃくちゃ重いです。もともとは生態シミュレータ的なものに
// したかったんですが、いまいちなので寝かせていました。Dropwaterを無理無理改造しているのでソースは汚いです。
//
// 曲はAlainMikuni氏(from gainaさんのsoundtest11 http://wonderfl.net/c/bB5h)からお借りしています。
// ありがとうございます。
//
// ※操作できません。微生物?の動きを眺めてください
package  
{
	import com.bit101.components.CheckBox;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageDisplayState;
	import flash.events.Event;
	import flash.events.FullScreenEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.ShaderFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.media.SoundMixer;
	import flash.net.URLRequest;
	import flash.system.Security;
	import flash.utils.ByteArray;
	import flash.utils.getTimer;
	/**
	 * ...
	 * @author TM
	 */
    [SWF(width=465,height=465,backgroundColor=0,frameRate=30)]
	public class soundSpectrumMetaRGB extends Sprite
	{
		private var snd:Sound;
		private var FFTswitch:Boolean = false;

		private var body_canvas : BitmapData; //worm 一体分を描画するcanvas
		private var canvas : BitmapData;
		private var canvasBmp : Bitmap;
		private var food : BitmapData;
		private var cylinder : Sprite = new Sprite();
		

		private var zeroPoint : Point = new Point(0, 0);
		private var dropimages : Vector.<MetaCircle> = new Vector.<MetaCircle>;
		private var uiBar : Sprite = new Sprite();
		
		private var tempPos : Point = new Point();
		private var tempRect : Rectangle = new Rectangle();
		
		private var metaEffect : MetaEffectPB = new MetaEffectPB();
		private var metaEffectFilter : ShaderFilter = new ShaderFilter(metaEffect);
		
		
		private var debugMode : Boolean = false;
		private var solidlMode : Boolean = false;

		private var shiftKeyIsDown : Boolean = false;
		private var mouseIsDown : Boolean = false;
		private var downPoint : Point = new Point();
		private var captureDrop : InvisibleWorm = null;
		private var captureRadius : Number = 0;

		private var fullscreenCheckbox : CheckBox;
		
		
		private var drops : Vector.<InvisibleWorm> = new Vector.<InvisibleWorm>;
		private var freep : int = -1;
		private const itemlimit : int = 30;

		public function soundSpectrumMetaRGB() 
		{
			Wonderfl.capture_delay( 30 );
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event=null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);

			addEventListener(Event.ENTER_FRAME, enterFrame);
			stage.addEventListener(MouseEvent.CLICK, mouseClick);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
			stage.addEventListener(FullScreenEvent.FULL_SCREEN, changeFullscreen);
			
			stage.doubleClickEnabled = true;
			
			WIDTH = stage.stageWidth;
			HEIGHT = stage.stageHeight;
			
			graphics.clear();
			graphics.beginFill(0xcedefa);
			graphics.drawRect(0, 0, WIDTH, HEIGHT);
			graphics.endFill();

			food = new BitmapData(WIDTH, HEIGHT, true, 0);
			food.noise(getTimer(), 0, 16, 15, true);
			addChild(new Bitmap(food));
			
			canvas = new BitmapData(WIDTH,HEIGHT, true, 0xff000000);
			canvasBmp = new Bitmap(canvas);
			addChild(canvasBmp);
			canvasBmp.filters = [ new DropShadowFilter(1, Math.PI/2, 0x404060, 0.5) ];
			
			body_canvas = canvas.clone();
			
			cylinder.graphics.clear();
			cylinder.graphics.beginFill(0, 0.8);
			cylinder.graphics.drawRect(-16, -16, stage.stageWidth+16*2, stage.stageHeight+16*2);
			cylinder.graphics.drawCircle(stage.stageWidth / 2, stage.stageHeight / 2, Math.max(stage.stageWidth, stage.stageHeight) *1.2 / 2);
			cylinder.graphics.endFill();
			cylinder.filters = [ new BlurFilter(16, 16) ];
			addChild(cylinder);
			
			addChild(uiBar);
			uiBar.graphics.clear();
			uiBar.graphics.beginFill(0, 0.7);
			uiBar.graphics.drawRect(0, 0, stage.stageWidth, 16);
			uiBar.graphics.endFill();
			uiBar.y = stage.stageHeight - 16;
			fullscreenCheckbox = new CheckBox( uiBar, 2, 2, "FULL SCREEN", fullscreenChecked);
			
			
			for (var r : Number = 0; r <= MAX_RADIUS; r++) {
				dropimages[r] = new MetaCircle(r + 1, r > 10 ? 1.0 : r / 20 +0.5 );
			}
			InvisibleWorm.metaImages = dropimages;

			playSound("http://www.takasumi-nagai.com/soundfiles/sound004.mp3");
			//Security.allowDomain("locadlhost");//	playSound("sound001.mp3"); // for local test

		}
		private function changeFullscreen(e:Event):void 
		{
			if (stage.displayState == StageDisplayState.FULL_SCREEN) {
				fullscreenCheckbox.selected = true;
			} else {
				fullscreenCheckbox.selected = false;
			}
		}
		
		private function fullscreenChecked(e:Event) : void
		{
			if (!fullscreenCheckbox.selected) {
				stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
				stage.displayState = StageDisplayState.NORMAL;
			} else {
				stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
				stage.displayState = StageDisplayState.FULL_SCREEN;
			}
		}
		
		private function playSound(sndUrl:String):void
		{
			snd = new Sound();
			var context:SoundLoaderContext = new SoundLoaderContext(10,true);
			var req:URLRequest = new URLRequest(sndUrl);
			var sndChannel:SoundChannel=new SoundChannel();
			snd.load(req, context);
			sndChannel = snd.play(0, 9999);
		}

		
		private function mouseClick(e:MouseEvent):void 
		{
			/* // pixelBender ToolKit用ソース画像取り込み
			var pFile :FileReference = new FileReference();
			var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(canvasBmp);
//			var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(new Bitmap(dropimages[99].densityImage));
			var imageByteArray:ByteArray = imageSnap.data as ByteArray;
			pFile.save(imageByteArray, "image.png");			
			*/
		}
		
		private function mouseUp(e:MouseEvent):void 
		{
			mouseIsDown = false;
			captureDrop = null;
		}
		
		private function mouseDown(e:MouseEvent):void 
		{
			mouseIsDown = true;
			downPoint.x = e.stageX;
			downPoint.y = e.stageY;
		}
		
		private function keyDown(e:KeyboardEvent):void 
		{
			if (e.charCode == 122) { // "Z"
				debugMode = !debugMode;
			} else if (e.charCode == 120) { // "X"
			} 
			shiftKeyIsDown = e.shiftKey;
		}
		private function keyUp(e:KeyboardEvent):void 
		{
			shiftKeyIsDown = e.shiftKey;
		}
		
		private function newItem( x : Number, y : Number) : InvisibleWorm
		{
			var cnt : int = drops.length;
			if (((itemlimit > 0) && cnt >= itemlimit) && (freep >= cnt-1)) return null;
			
			freep++;
			
			if (freep == cnt) {
				drops[cnt] = new InvisibleWorm(x, y);
			} else {
				drops[freep].regenerate(x, y);
			}
			drops[freep].index = freep;
			drops[freep].visible = true;

			
			return drops[freep];
		}
		private function remove(index : int) : void
		{
			var cnt : int = drops.length;
			var temp : InvisibleWorm = drops[index];
			var lastp : int = freep;

			temp.visible = false;
			//removeChild(temp);
			if (lastp != index) {
				drops[index] = drops[lastp];
				drops[index].index = index;
				drops[lastp] = temp;
			}
			freep = lastp - 1;
			
		}
		private var new_interval : int = 0;
		private function enterFrame(e:Event):void 
		{
			var i : int, j : int, drop : InvisibleWorm;
			var bytes:ByteArray = new ByteArray();
			var lx : Number, ly : Number, change_light : Boolean = false;
			SoundMixer.computeSpectrum(bytes, FFTswitch, 0);

			new_interval ++;

			var grow : Boolean = false;
			
			
			for (i = 0; i < 2; i++)
			{
				for (j = 0; j < 256; j++)
				{
					drop = null;
					var rf : Number = bytes.readFloat();
					if (rf < 0) {
						if ((new_interval >= 4) && (freep < itemlimit)) {
							drop = newItem( stage.stageWidth / 2, stage.stageHeight / 2);
							new_interval = 0;
						}
						//drop = newItem( (i < 1 ? j + 256 : 255 - j) * (stage.stageWidth / 512), (rf - 0.3) * 1000, rf * MAX_RADIUS);
					}
					var index : uint = 0;
					if (rf < 0) {
						index = (Math.random() * freep);
						drop = drops[index];
						drop.turn( -rf*50 );
					}

					if ((Math.abs(rf) > 0.1)) {
//						index = int(i * j / 25.6) % 10;
						index = (Math.random() * 10) >> 0;
						if ((index < freep) && (index < 10)) {
							drop = drops[index];
							//if (rf > 0) drop.grow( rf * 80 ); else
							drop.grow( rf * 1000 );
							grow = true;
						}
					} 
					
				}
			}
			
			if (!grow) {
				for (i = 0; (i < 10) && (i <= freep); i++) {
					drop = drops[i];
					drop.grow_target = 0;			
				}
			}
			

			var capture : Boolean = false;
			var mindist : Number = 1000;
			for (i = freep; i >= 0; i--) {
				var dropA : InvisibleWorm = drops[i];
				
				dropA.stepFrame();
				if (dropA.age <= 5) remove(i);
			}
			if (!capture) {
				captureDrop = null;
				captureRadius = 0.0;
			} else {
				captureDrop.speed = mouseIsDown ? 0.0 : 0.3;
			}

//			canvas.copyPixels(food, food.rect, zeroPoint);
			canvas.fillRect(canvas.rect, 0);
			
			for (i = freep; i >= 0; i--) {
				body_canvas.fillRect(body_canvas.rect, 0x000000);
				drop = drops[i];
				
				// render!
				drop.draw( body_canvas  , metaEffectFilter);
				canvas.copyPixels(body_canvas, body_canvas.rect, zeroPoint, null, null, true);

			}
			
		}
		
	}

}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shader;
import flash.filters.ShaderFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.ByteArray;

const MAX_RADIUS : Number = 50;
var WIDTH : int;
var HEIGHT : int;

class InvisibleWorm extends Bitmap
{
	public static const IW_EGG : int = 0; // 卵
	public static const IW_LARVAL : int = 1; // 幼生
	public static const IW_METAMORPHOSE : int = 2; // 変態期
	public static const IW_IMAGO_WORM : int = 3; // 成体-WORM型
	public static const IW_IMAGO_AMEBA : int = 4; // 成体-アメーバ型
	public static const IW_IMAGO_EEL : int = 5; // 成体-線虫型
		
	public static var metaImages : Vector.<MetaCircle>;
	
	public var index : int;
	//public var visible : Boolean;
	private var _radius : int;
	//public var x : Number;
	//public var y : Number;
	private var tx : Number;
	private var ty : Number;
	public var dx : Number;
	public var dy : Number;
	private var angle : Number = 0;
	public var fusion : Boolean;
	public var age : uint = 0;
	public var grow_target : uint = 0;
	public var turn_next : Number = 0.0;
	public var dead : Boolean = false;
	public var lastSplit : Number;
	public var befpos : Point = new Point();
	public var state : int = 0;
	public var speed : Number = 1.0;
	public var speed_cnt : Number = 0.0;
	
	public var lifeCycle : int = IW_EGG;
	public var imagoType : int = IW_IMAGO_WORM;
	
	private var track : Vector.<Point> = new Vector.<Point>;
	private var track_top : int = 0;
	private const TRACK_MASK : int = 0x1f;
	
	//public var width : Number;
	//public var height : Number;
	
	private var color_typ : Array = [2.0, 2.0, 2.0];
	private var color_offset : Array = [0.5, 0.5, 0.5];
	
	private var tempPos : Point = new Point();
	private var tempRect : Rectangle = new Rectangle();
	private var zeroPoint : Point = new Point(0, 0);
	
	public function InvisibleWorm(x : Number, y : Number)
	{
		for (var i : int = 0 ; i <= TRACK_MASK; i++) track[i] = new Point();
		regenerate(x, y);
	}
	
	public function regenerate(x : Number, y : Number) : void
	{
		this.x = x;
		this.y = y;
		befpos.x = x;
		befpos.y = y;
		lastSplit = y;
		tx = x;
		ty = y;
		this.dx = 0;
		this.dy = 0;
		radius = 10;
		fusion = false;
		visible = true;
		age = 151;// Math.random() * 60;
		grow_target = 0;
		color_typ[0] = 2.0;
		color_typ[1] = 2.0;
		color_typ[2] = 2.0;
		color_offset[0] = 0.5;
		color_offset[1] = 0.5;
		color_offset[2] = 0.5;
		var imago_sai : Number = Math.random();
		if (imago_sai < 0.3) {
			imagoType = IW_IMAGO_WORM;
		} else if (imago_sai < 0.6) {
			color_typ[0] = 4.0;
			color_typ[1] = 4.0;
			color_typ[2] = 2.0;
			color_offset[0] = 0.75;
			color_offset[1] = 0.75;
			color_offset[2] = 0.50;
			imagoType = IW_IMAGO_AMEBA;
		} else {
			
			color_typ[0] = 5.0;
			color_typ[1] = 5.0;
			color_typ[2] = 5.0;
			color_offset[0] = 0.80;
			color_offset[1] = 0.80;
			color_offset[2] = 0.80;
			
			imagoType = IW_IMAGO_EEL;
		}
		
		state = Math.random()*60;
		lifeCycle = IW_EGG;

		for (var i : int = 0 ; i <= TRACK_MASK; i++) {
			track[i].x = x;
			track[i].y = y;
		}
	}
	
	public function stepFrame() : void
	{
		if (speed <= 0.0) return;
		
		speed += (1.0 - speed) / 4;
		speed_cnt += speed;
		if (speed_cnt < 1.0) return;
		
		speed_cnt -= 1.0;
		
		if (lifeCycle > IW_EGG) {
			if (grow_target != 0) {
				age += (grow_target - age) / 4;
				if ( Math.abs(age - grow_target) <= 1.0 ) grow_target == 0;
			}
			if (grow_target == 0) {
				if (lifeCycle == IW_LARVAL) age /= 1.005;
				else age /= 1.05;
			}
		}
		state++;
		
		var rnd : Number, rad : Number;
		
		if (!dead) {
			radius = 5 + ((MAX_RADIUS - 5) / 1500) * age;
			
			if (radius <= 0) radius = 0;
			
			switch (lifeCycle) {
				case IW_EGG: {
					if (age > 150)  {
						lifeCycle = IW_LARVAL;
						angle = Math.random() * Math.PI * 2;
						dx = Math.cos(angle)*4;
						dy = Math.sin(angle)*4;
					} else {
						dx = 0;
						dy = 0;
					}
					break;
				}
				case IW_LARVAL: {
					if (age > 1200)  {
						lifeCycle = IW_METAMORPHOSE;
						state = 0;
					} else {
						var over : Boolean = false;
						if (((tx < 0)  || (tx > WIDTH)) && (tx * dx >= 0)) {
							angle = Math.atan2( HEIGHT / 2 - ty,  WIDTH / 2 - tx);
							over = true;
						}
						
						if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
							angle = Math.atan2( HEIGHT / 2 - ty,  WIDTH / 2 - tx);
							over = true;
						}
						if (((age % 10) == 0) || (turn_next > 0.0)) {
							if (!over) {
								rnd = Math.random() - 0.5;
								if (turn_next > 0.0) rnd *= turn_next;
								rad = rnd * Math.PI / 4;
								angle += rad;
								turn_next = 0.0;
							}
						}
						dx = Math.cos(angle)*radius/4;
						dy = Math.sin(angle)*radius/4;
					}
					break;
				}
				case IW_METAMORPHOSE: {
					dx *= 0.5;
					dy *= 0.5;
					
					if (state > 120) {
						radius *= 1.2;
						lifeCycle = imagoType;
					}
					break;
				}
				case IW_IMAGO_WORM: {
					over = false;
					if ((tx < 0)  || (tx > WIDTH)) {
						if (tx * dx >= 0) {
							angle -= Math.PI;
							over = true;
						}
					}
					
					if ((ty < 0) || (ty > HEIGHT)) {
						if (ty * dy >= 0) {
							angle -= Math.PI;
							over = true;
						}
					}
					if ((age % 10) == 0) {
						if (!over) {
							rnd = Math.random() - 0.5;
							
							rad = (rnd) * Math.PI / 4;
							angle += rad;
							turn_next = 0.0;
						}
					}
					dx = (Math.cos(angle)*0.7 + Math.cos(angle)*(Math.sin(state*Math.PI/30))*0.3)*radius/14;
					dy = (Math.sin(angle)*0.7 + Math.sin(angle)*(Math.sin(state*Math.PI/30))*0.3)*radius/14;

					break;
				}
				case IW_IMAGO_AMEBA: {
					over = false;
					if (((tx < 0)  || (tx > WIDTH)) && (tx * dx >= 0)) {
						angle -= Math.PI;
						over = true;
					}
					
					if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
						angle -= Math.PI;
						over = true;
					}
					if (((age % 50) == 0) || (turn_next > 0.0)) {
						if (!over) {
							rnd = Math.random() - 0.5;
							if (turn_next > 0.0) rnd *= turn_next;
							
							rad = (rnd) * Math.PI / 2;
							angle += rad;
							turn_next = 0.0;
						}
					}
					dx = (Math.cos(angle)*0.2 + Math.cos(angle)*(Math.sin(state*Math.PI/15))*0.8)*radius/32;
					dy = (Math.sin(angle)*0.2 + Math.sin(angle)*(Math.sin(state*Math.PI/15))*0.8)*radius/32;
					break;
				}
				case IW_IMAGO_EEL: {
					over = false;
					if (((tx < 0)  || (tx > WIDTH)) && (tx * dx >= 0)) {
						angle -= Math.PI;
						over = true;
					}
					
					if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
						angle -= Math.PI;
						over = true;
					}
					if ((age % 20) == 0) {
						if (!over) {
							rnd = Math.random() - 0.5;
							if (turn_next > 0.0) rnd *= turn_next*0.5;
							
							rad = (rnd) * Math.PI;
							angle += rad;
							turn_next = 0.0;
						}
					}
					dx = (Math.cos(angle)*0.6 + Math.cos(angle)*(Math.sin(state*Math.PI/15))*0.4)*radius/16;
					dy = (Math.sin(angle)*0.6 + Math.sin(angle)*(Math.sin(state*Math.PI/15))*0.4)*radius/16;
					break;
				}
			}
		} else {
			dx *= 0.99;
			dy *= 0.99;
		}
		tx += dx;
		ty += dy;

		x += (tx - x) / 4;
		y += (ty - y) / 4;

		var befdx : Number, befdy : Number, movdist : Number;

		switch (lifeCycle) {
			case IW_EGG: {
				
				break;
			}
			case IW_LARVAL: {
				befdx = x - befpos.x;
				befdy = y - befpos.y;
				movdist = Math.sqrt(befdx * befdx + befdy * befdy);
				if (movdist > radius / 2) {
					befpos.x = x - (radius / 2) * befdx / movdist;
					befpos.y = y - (radius / 2) * befdy / movdist;
				}
				befpos.x = track[ (track_top-2 ) & TRACK_MASK ].x;
				befpos.y = track[ (track_top-2 ) & TRACK_MASK ].y;
				break;
			}
			case IW_METAMORPHOSE: {
				befpos.x += (x - befpos.x) / 8;
				befpos.y += (y - befpos.y) / 8;
				break;
			}
			case IW_IMAGO_WORM: {
				var nextx : Number = track[ (track_top-8 ) & TRACK_MASK ].x;
				var nexty : Number = track[ (track_top-8 ) & TRACK_MASK ].y;

				befdx = x - nextx;
				befdy = y - nexty;
				movdist = Math.sqrt(befdx * befdx + befdy * befdy);
			
				if (movdist < radius / 3) {
					befpos.x += (nextx - befpos.x) / 32;
					befpos.y += (nexty - befpos.y) / 32;
				} else {
					befpos.x = nextx;
					befpos.y = nexty;
				}
					befpos.x = nextx;
					befpos.y = nexty;
			
				break;
			}
			case IW_IMAGO_AMEBA: {
				break;
			}
			case IW_IMAGO_EEL: {
				break;
			}
		}
		track[track_top].x = x;
		track[track_top].y = y;
		track_top = (track_top + 1) & TRACK_MASK;
		//if (age > 3000) dead = true;
	}
	
	public function grow(step : int) : void
	{
		if (step != 0) {
			grow_target = age + step;
			if (grow_target < 1) grow_target = 1;
			else if (grow_target > 1500) grow_target = 1500;
		} else grow_target = 0;
	}
	
	public function turn(level : Number) : void
	{	
		turn_next = level;
	}
	
	public function draw(target : BitmapData, filter : ShaderFilter ) : void
	{
		var elements : int = 1;
		switch (lifeCycle) {
			case IW_EGG: elements = 1; break;
			case IW_LARVAL: elements = 2; break;
			case IW_METAMORPHOSE: if (state > 60) elements = 4; else elements = 2;  break;
			case IW_IMAGO_WORM: elements = 4; break;
			case IW_IMAGO_AMEBA: elements = 4; break;
			case IW_IMAGO_EEL: elements = 4; break;
		}
		
		for (var ghost : int = 0; ghost < elements; ghost++) {
			
			var xx : int, yy : int, rr : int;
			rr = radius;
			
			switch (lifeCycle) {
				case IW_METAMORPHOSE: {
					if (ghost > 1) {
						rr = radius * ((state-60) / 60)*0.8 ;
						xx = (x  - rr) >> 0;
						yy = (y  - rr) >> 0;
					} else {
						if (ghost & 1) {
							rr = rr * 0.8;
							xx = (befpos.x  - rr) >> 0;
							yy = (befpos.y  - rr) >> 0;
						} else {
							xx = (x  - rr) >> 0;
							yy = (y  - rr) >> 0;
						}
					}
					break;
				}
				case IW_IMAGO_EEL:
				{
					rr = rr*0.9;
					xx = (track[ (track_top-ghost*8) & TRACK_MASK].x - rr) >> 0;
					yy = (track[ (track_top-ghost*8) & TRACK_MASK].y - rr) >> 0;
					break;
				}
				case IW_IMAGO_AMEBA:
				{
					var phase : Number;
					switch (ghost) {
						case 0: {
							phase = 0;
							break;
						}
						case 1: {
							phase = 30;
							break;
						}
						case 2: {
							phase = 90;
							break;
						}
						case 3: {
							phase = 60;
							break;
						}
					}
					xx = (track[ (track_top-ghost*3-1) & TRACK_MASK].x+Math.cos((phase+state)*Math.PI/60)*rr/3 - rr) >> 0;
					yy = (track[ (track_top-ghost*3-1) & TRACK_MASK].y+Math.sin((phase+state)*Math.PI/60)*rr/3 - rr) >> 0;
					break;
				}
				default:
				{
					if (ghost & 1) {
						rr = rr * 0.8;
						xx = (befpos.x  - rr) >> 0;
						yy = (befpos.y  - rr) >> 0;
					} else {
						xx = (x  - rr) >> 0;
						yy = (y  - rr) >> 0;
					}
					
				}
			}
			tempPos.x = xx;
			tempPos.y = yy;
			tempRect.x = tempPos.x;
			tempRect.y = tempPos.y;
			tempRect.width = width;
			tempRect.height = height;
			
			metaImages[rr].workImage.copyPixels( target, tempRect, zeroPoint );
			
			filter.shader.data.fore.input = metaImages[rr].densityImage;
			if ((ghost == elements-1) && (lifeCycle != IW_IMAGO_AMEBA)) {
				filter.shader.data.typ.value = [2.0, 2.0, 2.0];
				filter.shader.data.offset.value = [0.5, 0.5, 0.5];
			} else {
				filter.shader.data.typ.value = color_typ;
				filter.shader.data.offset.value = color_offset;
			}
			metaImages[rr].workImage.applyFilter( metaImages[rr].workImage, metaImages[rr].workImage.rect, zeroPoint, filter);
			target.copyPixels(metaImages[rr].workImage, metaImages[rr].workImage.rect, tempPos);
		}
	}
	
	public function get radius():int { return _radius; }
	
	public function set radius(value:int):void 
	{
		_radius = value < MAX_RADIUS ? value : MAX_RADIUS;
		bitmapData = metaImages[_radius >> 0].densityImage;
	}
}

class MetaCircle
{
	private var radius : Number = 0;
	private var maxdensity : Number = 1;
	private var visibleRatio : Number = 0.8;
	public  var densityImage : BitmapData;
	public  var workImage : BitmapData;
	private var pos : Point =  new Point();
	
	public function MetaCircle(r : Number, density : Number )
	{
		radius = r;
		maxdensity = density;
		densityImage = new BitmapData(r * 2+1, r * 2+1, true, 0);
		workImage = densityImage.clone();
		
		render();
	}
	
	public function density(r : Number) : Number
	{
		if (r < radius) {
			var t : Number = (r / radius);
			return maxdensity * (1 - t) * (1 - t);
		} else {
			return 0.0;
		}
	}
	
	private function render() : void
	{
		var h : int = densityImage.height;
		var w : int = densityImage.width;
		var h2 : int = h / 2;
		var w2 : int = w / 2;
		densityImage.lock();
		for (var y : int = 0; y < h; y++ ) {
			var rad1 : Number = Math.acos( ((h2-y)/h2) );
			var spanr : Number = Math.sin( rad1 ) * h2;
			
			for (var x : int = 0; x < w; x++) {
				var r : Number = Math.sqrt( (w2 - x) * (w2 - x) + (h2 - y) * (h2 - y) );
				var a : uint = density(r) * 255;
				if (a > 0) {
					var rad2 : Number = Math.acos(( (w2 - x) / w2));
					// 右手座標系 +X=左  +Y=上  +Z=手前
					var ny : Number = (h2 - y);
					var nx : Number = (Math.cos( rad2 ) * spanr);
					var nz : Number = Math.sin( rad2 ) * spanr;
					var l : Number = Math.sqrt( nx * nx + ny * ny +nz * nz );
					var nv : int = (Math.max(0,Math.min(255, nx / l * 128 + 128)) << 16) | (Math.min(255, ny / l * 128 + 128) << 8) | a;// (Math.min(255, nz / l * 128 + 128));
					
					if (a > 0) {
						// 本当はAチャンネルで濃度をあらわしたいが、Aの値を変えるとPixelBenderで参照しているRGBも変わってしまうのでしかたなくBに濃度を格納
						densityImage.setPixel32(x, y, (a << 24) | nv );
					}
				}
			}
		}
		densityImage.unlock();
	}
	
	public function drawTo(target : BitmapData, x : Number, y : Number) : void
	{
		pos.x = x-radius;
		pos.y = y-radius;
		target.copyPixels(densityImage, densityImage.rect, pos, null, null, true);
	}
}

import mx.utils.Base64Decoder;

class MetaEffectPB extends Shader
{
//	[Embed(source = 'MetaEffectPB.pbj', mimeType = 'application/octet-stream')]
//	private var pbj : Class;
	private var bcode : String = 
"pQEAAACkCQBEcm9wV2F0ZXKgDG5hbWVzcGFjZQBqcC5saW1hY29uAKAMdmVuZG9yAEVTVgCgCHZl"+
"cnNpb24AAgCgDGRlc2NyaXB0aW9uAG1ldGFOVgChAQIAAAxfT3V0Q29vcmQAoQECAAADcG9zaXRp"+
"b24AoQEDAQAOdHlwAKIDZGVmYXVsdFZhbHVlAEAAAABAAAAAQAAAAKEBAwIADm9mZnNldACiA2Rl"+
"ZmF1bHRWYWx1ZQA/AAAAPwAAAD8AAACjAARiYWNrAKMBBGZvcmUAoQIEAwAPZGVzdAAdBADBAAAQ"+
"AB0EADEEABAAAgQAMQAAsAAxBQDxBACwAR0GAPMFABsAMQUA8QQAEAAdBwDzBQAbAB0BABAGAMAA"+
"AQEAEAcAwAAdAwAQAQDAADIBABAAAAAAKgEAEAYAwAAdAYCAAIAAADQAAAABgAAAMgEAED8AAAAd"+
"BQDiBgAYAAIFAOIBAPwAMgEAEEAAAAAdCADiBQAYAAMIAOIBAPwAMgEAED8AAAAdBQDiBwAYAAIF"+
"AOIBAPwAMgEAEEAAAAAdCQDiBQAYAAMJAOIBAPwAHQUA4ggAGAABBQDiCQAYAB0IAOIFABgAJAEA"+
"EggAGAAdAgAQAQDAAAQFAOICAPwAAwUA4ggAGAAdCADiBQAYADIBABAAAAAAKgEAEAgAAAAdAYBA"+
"AIAAADQAAAABgEAABAEAEAEAAAADAQAQCAAAAB0EACABAMAAAQQAIAIAAAAdCACABACAADUAAAAA"+
"AAAABAEAEAEAAAADAQAQCAAAAB0EACACAAAAAgQAIAEAwAAdCACABACAADYAAAAAAAAAMgEAEAAA"+
"AAAqAQAQCABAAB0BgEAAgAAANAAAAAGAQAAEAQAQAQBAAAMBABAIAEAAHQQAIAEAwAABBAAgAgBA"+
"AB0IAEAEAIAANQAAAAAAAAAEAQAQAQBAAAMBABAIAEAAHQQAIAIAQAACBAAgAQDAAB0IAEAEAIAA"+
"NgAAAAAAAAAyAQAQAAAAACoBABAIAIAAHQGAQACAAAA0AAAAAYBAAAQBABABAIAAAwEAEAgAgAAd"+
"BAAgAQDAAAEEACACAIAAHQgAIAQAgAA1AAAAAAAAAAQBABABAIAAAwEAEAgAgAAdBAAgAgCAAAIE"+
"ACABAMAAHQgAIAQAgAA2AAAAAAAAAB0DAOIIABgANQAAAAAAAAAdAwDiBwAYADYAAAAAAAAA";

	public function MetaEffectPB()
	{
/*		
		var code : ByteArray = (new pbj()) as ByteArray;
		super( code );
*/		
		var dec : Base64Decoder = new Base64Decoder();
		dec.decode( bcode );
		super(dec.toByteArray());

		
	}
}
/*
<languageVersion : 1.0;>

kernel DropWater
<   namespace : "jp.limacon";
    vendor : "ESV";
    version : 2;
    description : "metaNV"; >
{
   parameter float2 position;
   input image4 back;
   input image4 fore;
   
   output pixel4 dest;
   
   
   void evaluatePixel()
   {
        float2 curPos = outCoord();
        pixel4 f0 = sampleNearest(fore, curPos-position);
        pixel4 b0 = sampleNearest(back, curPos);
        
        dest.a = f0.a+b0.a;
        if (f0.a > 0.0) {
            float3 v = (f0.xyz-0.5)*2.0 + (b0.xyz-0.5)*2.0;//(f0.xyz*2.0-1.0) + (b0.xyz*2.0-1.0);
            float l = length( v );
            v = v/l;
            if (v.r > 0.0) v.r = v.r/2.0+0.5; else v.r = 0.5-v.r/2.0;
            if (v.g > 0.0) v.g = v.g/2.0+0.5; else v.g = 0.5-v.g/2.0;
            if (v.b > 0.0) v.b = v.b/2.0+0.5; else v.b = 0.5-v.b/2.0;

            dest.rgb = v;
        } else {
            dest.rgb = b0.rgb;
        }
        
   }
}

*/