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

リアルな水滴を求めて

マウスクリックでタイルに水滴が付着します
* ----------------------------------------------
* ToDo: 大きな水滴はズリ落ちる
*       重なった水滴は合体する
* ----------------------------------------------
* 問題: DropShadowFilterは重複できない?
Get Adobe Flash player
by Kay 03 Mar 2009
/*
 * マウスクリックでタイルに水滴が付着します
 * ----------------------------------------------
 * ToDo: 大きな水滴はズリ落ちる
 *       重なった水滴は合体する
 * ----------------------------------------------
 * 問題: DropShadowFilterは重複できない?
 */
package {
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.GradientType;
	import flash.geom.Point;
	import flash.geom.Matrix;
	import flash.geom.Vector3D;
	import flash.geom.Rectangle;
	//import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.filters.BlurFilter;
	import flash.filters.DisplacementMapFilter;
	import flash.filters.DisplacementMapFilterMode;
	import flash.filters.DropShadowFilter;
	import flash.filters.BevelFilter;
	public class Take06 extends Sprite {
		private const SW:Number = stage.stageWidth;
		private const SH:Number = stage.stageHeight;
		private var drops:Vector.<Vector3D> = new Vector.<Vector3D>();
		private var backGround:Sprite = new Sprite();
		private var dropStage1:Sprite = new Sprite();
		private var dropStage2:Sprite = new Sprite();
		private var xStage    :Sprite = new Sprite();
		private var yStage    :Sprite = new Sprite();
		private var map:BitmapData;

		public function Take06():void {

			var stripe:BitmapData = new BitmapData(80,80,false,0xcccccc);
			stripe.fillRect(new Rectangle(2,2,76,76),0x9999cc);
			stripe.fillRect(new Rectangle(6,6,76,76),0x333366);
			stripe.fillRect(new Rectangle(4,4,76,76),0x666699);
			backGround.graphics.beginBitmapFill(stripe);
			backGround.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			backGround.graphics.endFill();
			addChild(backGround);
			addChild(dropStage1);
			addChild(dropStage2);

			map = new BitmapData(SW,SH,false,0x7f7f7f);

			// フィルターを駆使して水滴を表現する
			var fGlow1:GlowFilter = new GlowFilter();
			fGlow1.blurX = fGlow1.blurY = 16;
			fGlow1.color = 0x000066;
			fGlow1.strength = 10;
			fGlow1.inner = true;
			
			var fDropWhite:DropShadowFilter = new DropShadowFilter();
			fDropWhite.blurX = 4;
			fDropWhite.blurY = 4;
			fDropWhite.distance = 4;
			fDropWhite.angle = 70;		// 0で左(右回り)
			fDropWhite.color = 0x9999cc;
			fDropWhite.strength = 2;
			fDropWhite.alpha = 0.8;
			fDropWhite.inner = true;
			fDropWhite.knockout = true;

			var fDropBlue:DropShadowFilter = new DropShadowFilter();
			fDropBlue.blurX = fDropBlue.blurY = 16;
			fDropBlue.distance = 8;
			fDropBlue.angle = 270;		// 0で左(右回り)
			fDropBlue.color = 0x333366;
			fDropBlue.alpha = 0.7;
			fDropBlue.inner = true;
			fDropBlue.knockout = true;
			
			var fBevel:BevelFilter = new BevelFilter();
			fBevel.highlightColor = 0xffffff;
			fBevel.shadowColor = 0x000000;
			fBevel.angle = 270;
			fBevel.blurX = 16;
			fBevel.blurY = 16;
			fBevel.strength = 4;
			
			// DropShadowFilterは重複できない?
			// だったらステージを複数用意しちゃえ!
			dropStage1.filters = [fGlow1,fDropWhite];
			dropStage2.filters = [fGlow1,fDropBlue,fBevel];

			// 初期水滴を配置
			drops.push(new Vector3D(250,100,0,20));
			drops.push(new Vector3D(200,300,0,10));
			drops.push(new Vector3D(400,150,0,10));
			render();

			//addEventListener(Event.ENTER_FRAME, render);
			stage.addEventListener(MouseEvent.CLICK,addDrop);
		}
		private function addDrop(e:MouseEvent):void {
			drops.push(new Vector3D(mouseX,mouseY,0,Math.random()*10+10));
			render();
		}
		// ENTER_FRAMEで毎画面描画することを想定しています
		private function render():void {
			// dropStage1, 2 をクリア
			while (dropStage1.numChildren) dropStage1.removeChildAt(0);
			while (dropStage2.numChildren) dropStage2.removeChildAt(0);

			drops.forEach(drawDrop);
			
			// ビットマップデータに変換
			map.fillRect(map.rect,0x7f7f7f);
			map.draw(xStage);
			var yMap:BitmapData = new BitmapData(SW, SH, false, 0x7F7F7F); 
			yMap.draw(yStage); 
			map.copyChannel(yMap, yMap.rect, new Point(0, 0), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); 
			yMap.dispose();
			map.applyFilter(map,map.rect,new Point(0,0),new BlurFilter(20,20));
			
			// 背景に畳み込みフィルタを適用
			var xyFilter:DisplacementMapFilter = new DisplacementMapFilter(); 
			xyFilter.mapBitmap = map; 
			xyFilter.mapPoint = new Point(0,0);
			xyFilter.componentX = BitmapDataChannel.RED; 
			xyFilter.componentY = BitmapDataChannel.BLUE; 
			xyFilter.scaleX = 128; 
			xyFilter.scaleY = 128; 
			xyFilter.mode = DisplacementMapFilterMode.IGNORE; 
			backGround.filters = [xyFilter]; 

			// xStage,yStageをクリアする
			while (xStage.numChildren) xStage.removeChildAt(0);
			while (yStage.numChildren) yStage.removeChildAt(0);
			
		}
		private function drawDrop(drop:Vector3D, index:int, vector:Vector.<Vector3D>):void {
			// 落下(このバージョンでは動作しない)
			//vector[index].y += drop.w/400;
			
			// グラデーション設定
			var type:String = GradientType.LINEAR;
			var redColors :Array = [0xFF0000, 0x000000]; 
			var blueColors:Array = [0x0000FF, 0x000000]; 
			var alphas    :Array = [1, 1]; 
			var ratios    :Array = [0, 255]; 
			var xMatrix:Matrix = new Matrix(); 
			var yMatrix:Matrix = new Matrix(); 
			xMatrix.createGradientBox(drop.w*2, drop.w*2, 0,         drop.x-drop.w, drop.y-drop.w); 
			yMatrix.createGradientBox(drop.w*2, drop.w*2, Math.PI/2, drop.x-drop.w, drop.y-drop.w);
			// xStage
			var xCircle:Shape = new Shape();
			xCircle.graphics.beginGradientFill(type, redColors, alphas, ratios, xMatrix); 
			xCircle.graphics.drawCircle(drop.x,drop.y,drop.w-10);	// Glowフィルタとのズレを修正
			xCircle.graphics.endFill();
			xStage.addChild(xCircle);
			// yStage
			var yCircle:Shape = new Shape();
			yCircle.graphics.beginGradientFill(type, blueColors, alphas, ratios, yMatrix); 
			yCircle.graphics.drawCircle(drop.x,drop.y,drop.w-10);	// Glowフィルタとのズレを修正
			yCircle.graphics.endFill();
			yStage.addChild(yCircle);
			// dropStage1
			var circle1:Shape = new Shape();
			circle1.graphics.beginFill(0x0000ff);
			circle1.graphics.drawCircle(drop.x,drop.y,drop.w);
			circle1.graphics.endFill();
			dropStage1.addChild(circle1);
			// dropStage2
			var circle2:Shape = new Shape();
			circle2.graphics.beginFill(0x0000ff);
			circle2.graphics.drawCircle(drop.x,drop.y,drop.w);
			circle2.graphics.endFill();
			dropStage2.addChild(circle2);
		}
	}
}