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

風呂場forked from: 水滴のようなフィルタ効果

窓を流れる雨と合体したら風呂っぽくなった。
* とりあえずだったんでフィルタ効果は使用してません。
* クリックで初期化

マウス位置に水滴を表示する
Get Adobe Flash player
by demouth 28 Feb 2009
/*
 * 窓を流れる雨と合体したら風呂っぽくなった。
 * とりあえずだったんでフィルタ効果は使用してません。
 * クリックで初期化
 */
// forked from Kay's 水滴のようなフィルタ効果
/*
 * マウス位置に水滴を表示する
 */
package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	[SWF(width=465, height=465, backgroundColor=0x666666, frameRate=20)] 
	public class Main extends Sprite 
	{
		
		private var particles:Vector.<Particle> = new Vector.<Particle>();//雨粒
		private const NUM:int = 200;//表示する雨粒の数
		
		public function Main():void 
		{
			init();
		}
		
		private function init():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);
			var backGround:Sprite = new Sprite();
			backGround.graphics.beginBitmapFill(stripe);
			backGround.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			backGround.graphics.endFill();
			addChild(backGround);
			
			//雨粒作成
			this.create();
			
			this.addEventListener(Event.ENTER_FRAME , onEnterFrame);
			this.stage.addEventListener(MouseEvent.CLICK , removeAll);
		}
		
		private function onEnterFrame(e:Event):void
		{
			var w:uint = this.stage.stageWidth;
			var h:uint = this.stage.stageHeight;
			var num:uint = this.particles.length;
			var i:int;
			var j:int;
			for (i = 0; i < num; i++)
			{
				var p:Particle = this.particles[i];
				//有効な雨粒だったら
				if (!p.isDeleteFlg)
				{
					p.w = w;
					p.h = h;
					p.addAccelY(0.1);//下へ向かう
					//動いた時
					if (p.move())
					{
						//他の雨粒と接触していないかチェック
						for (j = 0; j < num; j++)
						{
							var pHitTest:Particle = this.particles[j];
							
							//有効な雨粒だったら
							if (!pHitTest.isDeleteFlg && i!=j)
							{
								//接触したら
								if (p.hitTestObject(pHitTest))
								{
									//マージする
									ParticleManager.margeParticles(p , pHitTest);
									//接触したほうは削除予定フラグ立てる
									pHitTest.isDeleteFlg = true;
								}
							}
						}
					}
				}
			}
			//有効な雨粒じゃなかったら削除する
			for (i = num-1; i >= 0; i--)
			{
				p = this.particles[i];
				if (p.isDeleteFlg)
				{
					this.removeChild(p);
					this.particles.splice(i,1);
				}
			}
			//新しい雨粒を作成
			this.create();
		}
		
		private function create(e:Event = null):void
		{
			
			var num:uint = this.NUM - this.particles.length;
			var w:uint = this.stage.stageWidth;
			var h:uint = this.stage.stageHeight;
			
			var i:int;
			for (i = 0; i < num; i++)
			{
				var p:Particle = new Particle();
				p.r = (Math.random() * 5) + 2;
				p.x = Math.random() * w;
				p.y = Math.random() * h;
				this.addChild(p);
				this.particles.push(p);
			}
		}
		
		private function removeAll(e:Event = null):void
		{
			var num:uint = this.particles.length;
			var i:int;
			for (i = 0; i < num; i++)
			{
				this.particles[i].isDeleteFlg = true;
			}
		}
	}
	
}

import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.display.Shape;
import flash.display.GradientType;
import flash.filters.GradientBevelFilter;
import flash.display.BitmapData;

class Particle extends Sprite
{
	
	public var isDeleteFlg:Boolean = false;
	
	public var w:Number = 1;
	public var h:Number = 1.2;
	
	public var vX:Number = 0;
	public var vY:Number = 0;
	
	private var _r:Number;//半径
	private var _area:Number;//面積
	private const PAI:Number = Math.PI;//π
	
	/**
	 * 半径
	 */
	public function get r():Number
	{
		return this._r;
	}
	
	/**
	 * 半径
	 */
	public function set r(r:Number):void
	{
		this._r = r;
		this._area = this.PAI * r * r;
		
		this.scaleX = this.scaleY = r;
	}
	
	/**
	 * 面積
	 */
	public function get area():Number
	{
		return this._area;
	}
	/**
	 * 面積
	 */
	public function set area(area:Number):void
	{
		this._area = area;
		this._r = Math.sqrt(area / this.PAI);
		
		this.scaleX = this.scaleY = this._r;
	}
	
	//■初期化■■■
	public function Particle(x:int=0 , y:int=0 , r:int=1) 
	{
		this.x = x;
		this.y = y;
		this.r = r;
		
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	private function init(e:Event = null):void 
	{
		removeEventListener(Event.ADDED_TO_STAGE, init);
		// entry point
		
		
		var g:Graphics = this.graphics;
		
		// フィルターマップを作成
		var matrix:Matrix = new Matrix();
		var type:String=GradientType.RADIAL;
		var redColors:Array=[0xff0000,0x990000,0x7f7f7f];
		var alphas   :Array=[1,1,0];
		var ratios   :Array=[0x11,0x99,0xff];
		matrix.createGradientBox(this.w, this.h, Math.PI/2);
		g.beginGradientFill(type, redColors, alphas, ratios, matrix, "pad","rgp",0.75);
		g.drawEllipse(0,0,this.w,this.h);
		g.endFill();
		var map:BitmapData=new BitmapData(this.width,this.height,false,0x7F7F7F);
		map.draw(this);
		
		// グラデーションベベルフィルタ
		var gvFilter:GradientBevelFilter = new GradientBevelFilter();
		gvFilter.distance = 1;
		gvFilter.angle  = 0xcc;
		gvFilter.colors = [0xffffff, 0x0000ff];
		gvFilter.alphas = [1,        0.9];
		gvFilter.ratios = [0x66,     0xdd];
		this.filters = [gvFilter];
		this.alpha = 0.5;
		//g.x = -100;
		
		this.scaleX = this.scaleY = this.r;
	}
	
	//■public■■■
	
	public function move():Boolean
	{
		var ret:Boolean = false;
		
		//ある程度の大きさになっているかどうか
		//大きければ下に移動する
		if (this.r > 6)
		{
			ret = true;
			
			this.x += this.vX;
			this.y += this.vY;
			
			if (this.x > this.w + this.r) this.isDeleteFlg = true;
			if (this.x < -this.r) this.isDeleteFlg = true;
			if (this.y > this.h + this.r) this.isDeleteFlg = true;
			if (this.y < -this.r) this.isDeleteFlg = true;
			
			//縦長にする
			this.r = this._r;
			this.scaleX += this.vX / 1;
			this.scaleY += this.vY / 1;
		}
		//大きくなければ移動しない
		else
		{
			this.vX = this.vY = 0;
		}
		
		//動いたかどうかを返す
		//動いたらtrue
		return ret;
	}
	
	public function addAccelX(accel:Number):void
	{
		this.vX += accel;
	}
	
	public function addAccelY(accel:Number):void
	{
		this.vY += accel;
	}
	
}

class ParticleManager 
{
	
	public function ParticleManager() 
	{
		
	}
	/**
	 * p1とp2をp1にマージ
	 * @param	p1
	 * @param	p2
	 */
	public static function margeParticles(p1:Particle , p2:Particle):void
	{
		p1.vX = (p1.vX + p2.vX) ;
		p1.vY = (p1.vY + p2.vY) ;
		
		p1.area = p1.area + p2.area ;
		
		var areaRatio:Number;
		var moveX:Number;
		var moveY:Number;
		if (p1.area >= p2.area)
		{
			areaRatio = p2.area / p1.area;
			moveX = (p2.x - p1.x) * areaRatio;
			moveY = (p2.y - p1.y) * areaRatio;
		}
		else
		{
			areaRatio = p1.area / p2.area;
			moveX = (p1.x - p2.x) * areaRatio;
			moveY = (p1.y - p2.y) * areaRatio;
		}
		p1.x += moveX;
		p1.y += moveY;
		p1.addAccelX(moveX / 10);
	}
	
}