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

moku-moku(forked from: fussa-fussa)

1日1Flash。別のものを作っていたけど間に合いそうに無いのでfussa-fussaを
改造。マッチの煙というよりも線香の煙
(+)をクリックすると、吸引あり/なしの切り替え
いまいちイメージどおりになっていない。煙も斜めに出ているような・・・・
/**
 * Copyright zendenmushi ( http://wonderfl.net/user/zendenmushi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6VIx
 */

// 1日1Flash。別のものを作っていたけど間に合いそうに無いのでfussa-fussaを
// 改造。マッチの煙というよりも線香の煙
//
// (+)をクリックすると、吸引あり/なしの切り替え

// いまいちイメージどおりになっていない。煙も斜めに出ているような・・・・
package  
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import frocessing.core.F5BitmapData2D;
	/**
	 * ...
	 * @author TMaeda
	 */
    [SWF(width=465,height=465,backgroundColor=0,frameRate=60)]
	public class ClackledHair extends Sprite
	{
		private var back  : F5BitmapData2D;
		private var canvas : F5BitmapData2D;
		private var smoke : BitmapData;
		private var hairs : Vector.<Tail> = new Vector.<Tail>;
		private var blur : BlurFilter = new BlurFilter(6, 6, 1);
		private var colorTrans : ColorTransform = new ColorTransform(1.0,1.0,1.0, 0.9);
		
		private var center : Point = new Point();
		private var isDown : Boolean = false;
		private var tempPos : Point = new Point();
		private var lastPos : Point = new Point();
		private var rootPos : Point = new Point();
		private var zeroPos : Point = new Point(0, 0);
		private var plusBall : Point = new Point();
		private var negative : Boolean = false;
		private var selIndex : int = -1;
		private var rad : Number = 0;
		private var smokePos : Point = new Point();
		
		public function ClackledHair() 
		{
			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.MOUSE_DOWN, mouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			
			back = new F5BitmapData2D(stage.stageWidth, stage.stageHeight, true, 0);
			addChild(new Bitmap(back.bitmapData));
			
			canvas = new F5BitmapData2D(stage.stageWidth, stage.stageHeight, true, 0xffffff);
			addChild( new Bitmap(canvas.bitmapData) );
			
			smoke = new BitmapData(32, 32, true, 0x80808080);
			smoke.perlinNoise(16, 16, 8, 0, true, false, 7, true);
			//addChild( new Bitmap(smoke));
			
			center.x = stage.stageWidth / 2;
			center.y = stage.stageHeight / 2;
			for (var i : int = 0 ; i < 5; i++) {
				hairs[i] = new Tail();
				hairs[i].init(center, 270, 8, 32+Math.random()*16, 1, false);
			}
			
			rootPos.x = stage.stageWidth*3/5;
			rootPos.y = stage.stageHeight*3/4;
			plusBall.x = 100;
			plusBall.y = 100;
		}
		
		private function dist(a : Point, b : Point): Number
		{
			return Math.sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
		}
		
		private function mouseDown(e:MouseEvent):void 
		{
			lastPos.x = e.stageX;
			lastPos.y = e.stageY;
			selIndex = (dist(lastPos, plusBall) < 8) ? 0 : (dist(lastPos, rootPos) < 8) ? 1 : -1;
			isDown = true;
		}
		
		private function mouseUp(e:MouseEvent):void 
		{
			if ((dist(lastPos, plusBall) < 1) && (selIndex == 0)) {
				negative = !negative;
			}
			isDown = false;
		}
		
		private function smokeMoveTo(x : int, y : int) : void
		{
			smokePos.x = x;
			smokePos.y = y;
		}
		
		private function smokeLineTo(x : int, y : int, p : int, acoeff : Number) : int
		{
			var a : Number;
			var dx : int = x - smokePos.x, dy : int = y - smokePos.y;
			var adx : int = Math.abs(dx), ady : int = Math.abs(dy);
			var d : int = 0;
			var i : int, j : int;
			var x0 : int, y0 : int, x1 : int, y1 : int, xsign : int, ysign : int;
			var sx : int = p % 32, sy : int = (p / 32) % 32;
			var col : int, src : int;

			xsign = smokePos.x > x ? -1 : 1;
			ysign = smokePos.y > y ? -1 : 1;
			
			if (adx > ady) {
				x0 = xsign > 0 ? smokePos.x : x;
				y0 = xsign > 0 ? smokePos.y : y;
				x1 = xsign < 0 ? smokePos.x : x;
				y1 = xsign < 0 ? smokePos.y : y;
				//ysign = xsign  < 0 ? -ysign : ysign;
				
				j = smokePos.y;
				for ( i = smokePos.x; i != x; i += xsign) {
					d += ady;
					if (d > adx) {
						d -= adx;
						j += ysign;
					}
					src = canvas.bitmapData.getPixel32(i, j) & 0xff;
					col = smoke.getPixel32(sx, sy) & 0xff;
					sx = (sx+1)  & 0x1f;
					if (sx == 0) sy = (sy + 1) & 0x1f;
					a = Math.min(acoeff*255, Math.max(col , src )& 0xff);
					
					canvas.bitmapData.setPixel32(i, j, (0xff << 24) | (a << 16) | (a << 8) | a);
					p++;
				}
			} else if (dy != 0) {
				x0 = ysign > 0 ? smokePos.x : x;
				y0 = ysign > 0 ? smokePos.y : y;
				x1 = ysign < 0 ? smokePos.x : x;
				y1 = ysign < 0 ? smokePos.y : y;
				//xsign = ysign  < 0 ? -xsign : xsign;

				j = smokePos.x;
				for ( i = smokePos.y; i != y; i += ysign ) {
					d += adx;
					if (d > ady) {
						d -= ady;
						j += xsign;
					}
					src = canvas.bitmapData.getPixel32(i, j) & 0xff;
					col = smoke.getPixel32(sx, sy) & 0xff;
					//col = (0xff-(col & 0xff)) << 24 | (0xffffff);
					sx = (sx+1)  & 0x1f;
					if (sx == 0) sy = (sy+1) & 0x1f;
					a = Math.min(acoeff*255, Math.max(col , src));
					canvas.bitmapData.setPixel32(j,i, (0xff << 24) | (a << 16) | (a << 8) | a);
					p++;
				}
			}
			
			smokePos.x = x;
			smokePos.y = y;

			return p;
		}
		
		private var smoke_state : int = 0;
		private function enterFrame(e:Event):void 
		{
			var i : int, j : int;
			var hair_len : int;
			var hair_cnt : int = hairs.length;
			var p : int = smoke_state;
			
			smoke_state = (32 * 32 + smoke_state - 4) % (32 * 32);
			
			
			if (isDown) {
				switch (selIndex) {
					case 0: {
						plusBall.x = stage.mouseX;
						plusBall.y = stage.mouseY;
						break;
					}
					case 1: {
						rootPos.x += (stage.mouseX-rootPos.x)/4;
						rootPos.y += (stage.mouseY-rootPos.y)/4;
						break;
					}
				}
			}
			
			rad += Math.random();
			
			back.bitmapData.fillRect(back.bitmapData.rect, 0);
			back.beginDraw();
			back.beginFill(0xff8000);
			back.noStroke();
			back.circle(rootPos.x, rootPos.y, 2);
			back.endFill();
			back.stroke(0xff, 0xff, 0xff);
			back.noFill();
			back.circle(rootPos.x, rootPos.y, 8);
			
			back.circle(plusBall.x, plusBall.y, 8);
			back.moveTo(plusBall.x - 3, plusBall.y);
			back.lineTo(plusBall.x + 3, plusBall.y);
			
			if (!negative) {
				back.moveTo(plusBall.x , plusBall.y - 3);
				back.lineTo(plusBall.x , plusBall.y + 3);
			}
			back.endDraw();
			
			canvas.beginDraw();
			canvas.bitmapData.lock();
			for (i = 0; i < hair_cnt; i++) {
				var tail : Tail = hairs[i];
				tempPos.x = rootPos.x + Math.cos(rad) * 4;
				tempPos.y = rootPos.y + Math.sin(rad) * 8;
				
				tail.stepFrame(tempPos, 0, negative? null : plusBall);
				hair_len = tail.tails.length;
				smokeMoveTo(tail.rootpos.x, tail.rootpos.y);
//				canvas.moveTo(tail.rootpos.x, tail.rootpos.y);
				for (j = 0; j < hair_len; j++) {
					canvas.stroke(0xff*j/hair_len, 0x80, 0x40);
					p = smokeLineTo(tail.tails[j].term.x, tail.tails[j].term.y, p, (hair_len - j) / hair_len);
					//canvas.lineTo(tail.tails[j].term.x, tail.tails[j].term.y);
				}
			}
			canvas.bitmapData.unlock();
			canvas.endDraw();
			canvas.bitmapData.applyFilter(canvas.bitmapData, canvas.bitmapData.rect, zeroPos, blur);
			canvas.bitmapData.colorTransform(canvas.bitmapData.rect, colorTrans);
		}
		
	}

}

import flash.geom.Point;

class Tail
{
	public  var tails : Vector.<TailItem>;
	public  var rootpos : Point = new Point();
	public  var rootangle : Number;
	private var flexAngle : Number;
	private var segLen : int;
	public  var segCnt : int;
	private var temppos1 : Point = new Point();
	private var temppos2 : Point = new Point();
	private var befterm : Point = new Point();
	private var autoWave : Boolean;
	private var waveState : int;
	private var absorb : Number = 0;
	
	private const maxlen : int = 64;
	
	public function Tail()
	{
		tails = new Vector.<TailItem>;
	}
	
	public function init(pos : Point, angle : Number, seglen : int, len : int, flexlevel : Number, autowave : Boolean = true ) : void
	{
		flexAngle = Math.min(flexlevel, 1.0)*2 * Math.PI;
		rootangle = angle * Math.PI / 180;
		segCnt = Math.min(maxlen, len);
		segLen = seglen;
		autoWave = autowave;
		waveState = 0;
		
		rootpos.x = pos.x;
		rootpos.y = pos.y;
		
		for (var i : int = 0; i < segCnt; i++) {
			/*if (i < tails.length)*/ tails[i] = new TailItem;
			tails[i].pos.x = pos.x;
			tails[i].pos.y = pos.y;
			tails[i].len = segLen+Math.random()*(segLen);
			tails[i].angle = 0;
		}
		
	}
	
	public function tailPos(index : int, /*out*/ pos : Point, term : Point = null) : void
	{
		if (index < segCnt) {
			pos.x = tails[index].pos.x;
			pos.y = tails[index].pos.y;
			if (term) {
				term.x = tails[index].term.x;
				term.y = tails[index].term.y;
			}
		}
	}
	
	public function stepFrame(newpos : Point, rotate_angle : Number, tail_target : Point = null) : void
	{
		var i : int, cosa : Number, sina : Number, rad : Number;
		var angle : Number = rootangle+rotate_angle;
		waveState = (waveState + 1) & 0x3f;
		if (autoWave) {
			if (waveState >= 0x20) {
				angle = angle + (0x20 - (waveState & 0x1f) - 0x10)*Math.PI/180;
			} else {
				angle = angle + (waveState-0x10)*Math.PI/180;
			}
		}
		
		if (tail_target) {
			absorb = 1.0;
		} else if (absorb > 0) {
			absorb /= 2;
		} else absorb = 0;
		
		rootpos.x = newpos.x;
		rootpos.y = newpos.y;
		
		for (i = 0; i < segCnt; i++) {
			if (i == 0) {
				tails[i].pos.x = newpos.x;
				tails[i].pos.y = newpos.y;
				if (autoWave) {
					tails[i].pos.x += Math.random() * 8-4;
					tails[i].pos.y += Math.random() * 8-4;
				}
			} else {
				tails[i].pos.x += (tails[i-1].term.x-tails[i].pos.x)/((i*absorb/4+1));
				tails[i].pos.y += (tails[i-1].term.y-tails[i].pos.y)/((i*absorb/4+1));
			}
			computeUnitVector(Math.cos(angle) * segLen, Math.sin(angle) * segLen, 0, 0, temppos1);
			if (!computeUnitVector(tails[i].term.x, tails[i].term.y, tails[i].pos.x, tails[i].pos.y, temppos2)) {
				temppos2.x = temppos1.x;
				temppos2.y = temppos1.y;
			}
			cosa = dotProduct(temppos1.x, temppos1.y, temppos2.x, temppos2.y);
			sina = crossProductZ(temppos1.x, temppos1.y, temppos2.x, temppos2.y);
			if (cosa < -1) rad = Math.PI; else if (cosa > 1) rad = 0; else rad = Math.acos(cosa);
			//trace(cosa + " " + rad);
			if (cosa < 0) rad = Math.PI-rad;
			if (sina < 0) rad = -rad;
			//trace(">"+cosa + " " + rad);
			
			if ((rad < 0) && ( -flexAngle > rad)) rad = -flexAngle;
			if ((rad > 0) && (  flexAngle < rad)) rad =  flexAngle;
			
			rad += (0-rad) /4;
			tails[i].angle = angle+rad;
			angle = tails[i].angle;
			
			tails[i].term.x = tails[i].pos.x + Math.cos(angle)*tails[i].len;
			tails[i].term.y = tails[i].pos.y + Math.sin(angle)*tails[i].len;
			
			
		}
		if (tail_target) {
			befterm.x = tail_target.x;
			befterm.y = tail_target.y;
			for (i = segCnt - 1; i > 0; i--) {
				temppos2.x = tails[i].term.x + (befterm.x - tails[i].term.x) / ((segCnt - i)/2 + 1) ;
				temppos2.y = tails[i].term.y + (befterm.y - tails[i].term.y) / ((segCnt - i)/2 + 1) ;
				if (computeUnitVector(temppos2.x, temppos2.y, tails[i].pos.x, tails[i].pos.y, temppos1)) {
					tails[i].term.x = temppos2.x;
					tails[i].term.y = temppos2.y;
					tails[i].pos.x = temppos2.x - (temppos1.x)*tails[i].len;
					tails[i].pos.y = temppos2.y - (temppos1.y)*tails[i].len;
					befterm.x = tails[i].pos.x;
					befterm.y = tails[i].pos.y;
				}
			}
		}
	}

	public function computeUnitVector(x0 : Number, y0 : Number, x1 : Number, y1 : Number, /*out*/ u : Point) : Boolean
	{
		var len : Number = Math.sqrt( (y0 - y1) * (y0 - y1) + (x0 - x1) * (x0 - x1) );
		if (len > 0) {
			u.x = (x0 - x1) / len;
			u.y = (y0 - y1) / len;
			return true;
		} else return false;
	}

	public function dotProduct(x0 : Number, y0 : Number, x1 : Number, y1 : Number) : Number
	{
		return x0 * x1 + y0 * y1;
	}
	
	public function crossProductZ(x0 : Number, y0 : Number, x1 : Number, y1 : Number) : Number
	{
		return x0 * y1 - y0 * x1;
	}
	
	
}
	
class TailItem
{
	public var pos : Point = new Point();
	public var angle : Number;
	public var term : Point = new Point();
	public var len : Number;
}