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

流れる粒子

Get Adobe Flash player
by termat 29 Mar 2010
    Embed
/**
 * Copyright termat ( http://wonderfl.net/user/termat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/htHu
 */

package
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import com.bit101.components.*;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	[SWF(width = "480", height = "480", backgroundColor = "0xffffff", fps = "30")] 
	public class Practice46 extends Sprite{
		private var list:Vector.<Particle>;
		private var num:int = 400;
		private var dt:Number = 0.15;
		private var mode:int = 0;
		private var pos:Point, pos2:Point;
		private var faucet:MovieClip;
		private var isDouble:Boolean = false;
		
		public function Practice46() {
			list = new Vector.<Particle>();
			for (var i:int = 0; i < num; i++) {
				var p:Particle = new Particle(0, 0, 0, 0, 1000);
				list.push(p);
			}
			stage.doubleClickEnabled = true;
			addEventListener(Event.ENTER_FRAME, update);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			stage.addEventListener(MouseEvent.CLICK, singleClick);
			stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClick);
			var prob1 : RadioButton = new RadioButton(this, 420, 5, "Inflow", true, function(e:Event):void { mode = 0; } );
			var prob2 : RadioButton = new RadioButton(this, 420, 20, "Draw Wall", false, function(e:Event):void { mode = 1; } );
			var prob3 : RadioButton = new RadioButton(this, 420, 35, "Cut Wall", false, function(e:Event):void { mode = 2; } );
			faucet = new MovieClip();
			faucet.graphics.lineStyle(4, 0x000066);
			faucet.graphics.drawCircle(0, 0, 12);
			faucet.x = 32; faucet.y = 20;
			addChild(faucet);
			initWall();
			Wonderfl.capture_delay(30);
		}
		
		private function singleClick(e:MouseEvent):void {
			isDouble = false;
		}
		
		private function doubleClick(e:MouseEvent):void {
			isDouble = true;
		}
		
		private function initWall():void {
			setWall(new Point(18, 55), new Point(370, 165));
			setWall(new Point(452, 122), new Point(452, 226));
			setWall(new Point(453, 214), new Point(283, 254));
			setWall(new Point(230, 262), new Point(84, 294));
			setWall(new Point(19, 267), new Point(19, 371));
			setWall(new Point(19, 374), new Point(100, 446));
			setWall(new Point(100, 446), new Point(203, 446));
			setWall(new Point(203, 446), new Point(249, 382));
			setWall(new Point(253, 418), new Point(411, 448));
		}
		
		private function update(e:Event):void {
			if (mode==0) {
				for each(var p:Particle in list) {
					if (p.isAlive) continue;
					p.x = faucet.x;
					p.y = faucet.y;
					p.isAlive = true;
					p.color = 0x0000ff;
					break;
				}
			}
			this.graphics.clear();
			for each(p in list) {
				if (p.isAlive) {
					p.draw(this.graphics);
					p.calcBuoyancy(dt);
					p.calcConvection(dt);
					p.updateAlive();
				}
			}
			Particle.calcCollision(dt, list);
			if (pos2 != null) {
				if (mode == 1) {
					graphics.lineStyle(1,0xff0000);
					graphics.moveTo(pos.x, pos.y);
					graphics.lineTo(pos2.x, pos2.y);
				}else {
					graphics.lineStyle(1, 0xff0000);
					graphics.drawRect(Math.min(pos.x, pos2.x), Math.min(pos.y, pos2.y), Math.abs(pos.x - pos2.x), Math.abs(pos.y - pos2.y));
				}
			}
			if (isDouble) {
				faucet.x = mouseX;
				faucet.y = mouseY;
				isDouble = false;
			}
		}
		
		private function mouseDown(e:MouseEvent):void {
			if (mode >= 1) pos = new Point(e.stageX, e.stageY);
		}
		
		private function setWall(p1:Point, p2:Point):void {
					var vx:Number = p2.x - p1.x;
					var vy:Number = p2.y - p1.y;
					var lg:Number = Math.sqrt(vx * vx + vy * vy);
					vx *= 1.0 / lg;
					vy *= 1.0 / lg;
					var xx:Number = p1.x;
					var yy:Number = p1.y;
					while (true) {
						var p:Particle = new Particle(xx, yy, 0, 0, 1000);
						p.isAlive = true;
						p.isFix = true;
						p.color = 0x888888;
						list.push(p);
						xx += vx * Particle.radius/2.0;
						yy += vy * Particle.radius/2.0;
						if (lg < Math.sqrt(Math.pow(xx - p1.x, 2) + Math.pow(yy - p1.y, 2))) break;
					}
		}
		
		private function mouseUp(e:MouseEvent):void {
			if (pos != null && pos2 != null) {
				if (mode == 1) {
					setWall(pos,pos2);
				}else {
					var r:Rectangle = new Rectangle(Math.min(pos.x, pos2.x), Math.min(pos.y, pos2.y), Math.abs(pos.x - pos2.x), Math.abs(pos.y - pos2.y));
					for each(var p:Particle in list) {
						if (r.contains(p.x, p.y)) {
							p.x = 0; p.y = 0;
							p.vx = 0; p.vy = 0;
							p.isFix = false; p.isAlive = false;
						}
					}
				}
			}
			pos = null;
			pos2 = null;
		}
		
		private function mouseMove(e:MouseEvent):void {
			if (pos != null) pos2 = new Point(e.stageX, e.stageY);
		}
	}
}
import flash.display.Graphics;
import flash.geom.Rectangle;

class Particle {
	public static var rect:Rectangle = new Rectangle(0, 0, 480, 480);
	public static var radius:Number = 8.0;
	public const GRAV:Number = 9.8;
	public const COL_RATE:Number=1.6;
	public var x:Number=0.0 , y:Number=0.0; 
	public var vx:Number=0.0 , vy:Number=0.0; 
	public var isAlive:Boolean = false;
	public var isFix:Boolean = false;
	public var dencity:Number = 1000;
	public var color:uint = 0x0000ff;
	
	public function Particle(x:Number , y:Number , vx:Number , vy:Number, d:Number) {
		this.x = x ;	this.y = y ;
		this.vx = vx ;	this.vy = vy ;
		dencity = d;
	}
	
	public function updateAlive():void {
		isAlive = rect.contains(x, y);
		if (!isAlive) { vx = 0; vy = 0; x = 0; y = 0; }
	}
	
	public function draw(g:Graphics):void {
		if (isAlive) {
			g.beginFill(color);
			g.drawCircle(x,y,radius);
			g.endFill();
		}
	}
	
	public function distanceSq( p:Particle ):Number { 
		var xx:Number = x - p.x;
		var yy:Number = y - p.y;
		return ( xx * xx + yy * yy) ;
	}
	
	public function getVerocity():Number { 
		return Math.sqrt(vx * vx + vy * vy) ;
	}
	
	public function calcBuoyancy(dt:Number ):void { 
		if(!isAlive||isFix) return;
		vy += GRAV * dt ;
	}
	
	public function calcConvection( dt:Number ):void { 
		if(!isAlive||isFix) return;
		x += vx * dt ;
		y += vy * dt ;
	}
	
	public static function calcCollision(dt:Number , ps:Vector.<Particle>):void {
		var rr2:Number = 4 * radius * radius;
		var dist:Number;
		for (var i:int = 0; i < ps.length; i++) {
			if (!ps[i].isAlive) continue;
			for (var j:int = i + 1; j < ps.length; j++) {
				if (!ps[j].isAlive) continue;
				dist = ps[i].distanceSq(ps[j]);
				if (dist < rr2) ps[i].collision(dt, ps[j], rr2);
			}
		}
	}
	
	public function collision(dt:Number , p:Particle, rr2:Number):void {
		var xx:Number = p.x - x ;
		var yy:Number = p.y - y ;
		var m1:Number = dencity;
		var m2:Number = p.dencity;
		var rr:Number = Math.sqrt(rr2);
		var mm:Number = m1 + m2 ;
		var gx:Number = ( m1 * vx + m2 * p.vx ) / mm ;
		var gy:Number = ( m1 * vy + m2 * p.vy ) / mm ;
		gx = m1 * ( vx - gx ) ;
		gy = m1 * ( vy - gy ) ;
		var vabs:Number = ( gx * xx + gy * yy) / rr ;
		if( vabs < 0.0 ) return;
		var vrat:Number = 1.0 + COL_RATE;
		gx = vrat * vabs * xx / rr ;
		gy = vrat * vabs * yy / rr ;
		if(!isFix){
			vx -= gx / m1;
			vy -= gy / m1;
			x -= dt * gx / m1;
			y -= dt * gy / m1;
		}
		if(!p.isFix) {
			p.vx += gx / m2;
			p.vy += gy / m2;
			p.x += dt * gx / m2;
			p.y += dt * gy / m2;
		}
	}
}