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

窓を流れる雨

窓を流れる雨風。
クリックで初期化。
//窓を流れる雨風。
//クリックで初期化。
package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	[SWF(width=465, height=465, backgroundColor=0xFFFFFF, frameRate=20)] 
	public class Main extends Sprite 
	{
		
		private var particles:Vector.<Particle> = new Vector.<Particle>();//雨粒
		private const NUM:int = 200;//表示する雨粒の数
		
		private var bd:BitmapData = new BitmapData(465, 465);
		private var b:Bitmap;//残像用のBitmap
		private var s:Sprite;//だんだん消えていくためのSprite
		
		public function Main():void 
		{
			init();
		}
		
		private function init():void 
		{
			//残像用セットアップ
			this.s = new Sprite();
			this.s.graphics.beginFill(0xFFFFFF , 0.3);
			this.s.graphics.drawRect(0, 0, 465, 465);
			this.s.graphics.endFill();
			this.b = new Bitmap(this.bd);
			this.addChild(this.b);
			
			//雨粒作成
			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.bd.draw(this.s);
			this.bd.draw(this);
			//新しい雨粒を作成
			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;

class Particle extends Sprite
{
	
	public var isDeleteFlg:Boolean = false;
	
	public var w:uint = 1;
	public var h:uint = 1;
	
	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;
		g.beginFill(0xBBDDFF);
		g.drawCircle(0, 0, 1);
		g.endFill();
		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);
	}
	
}