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

マウスに毛が絡まった

単純にlineToで繋げると直線っぽくなってしまうのを
* CatmullRom曲線を使ってそれらしく
* curveToで描けば良さそうなものなんですが…
Get Adobe Flash player
by SeeDa 23 Jun 2009
/*
 * 単純にlineToで繋げると直線っぽくなってしまうのを
 * CatmullRom曲線を使ってそれらしく
 * curveToで描けば良さそうなものなんですが…
 */


package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	[SWF(width="465", height="465", backgroundColor="0xffffff", frameRate="30")]
	public class Rope extends Sprite {
		
		private var dots:Vector.<Dot> = new Vector.<Dot>();
		private var dotNum:uint = 10;
		
		public function Rope():void {
			for (var i:uint = 0; i < dotNum; i++) {
				var dot:Dot = new Dot();
				if (i > 0) {
					dot.target = dots[i-1];
				}
				dots.push(dot);
				addChild(dot);
			}
			addEventListener(Event.ENTER_FRAME, xMove);
                        Wonderfl.capture_delay( 30 ); 
		}
		private function xMove(e:Event):void {
			graphics.clear();
			/*
			// 単純に描画すると直線を繋いでいることがバレバレ
			graphics.lineStyle(6,0x000000);
			graphics.moveTo(mouseX, mouseY);
			for (var i:Number = 1; i < dotNum; i++) {
				graphics.lineTo(dots[i].x, dots[i].y);
			}
			*/
			
			/*
			// drawPathを使っても同じこと
			var points:Vector.<Number> = new Vector.<Number>();
			var commands:Vector.<int> = new Vector.<int>();
			points.push(mouseX,mouseY);
			commands.push(1);
			for (var i:Number = 1; i < dotNum; i++) {
				points.push(dots[i].x, dots[i].y);
				commands.push(2);
			}
			graphics.lineStyle(6,0x000000);
			graphics.drawPath(commands, points);
			*/
			
			// CatmullRom曲線を使ってポイントを補完する
			// (といっても短い直線なんですが…)
			var points:Vector.<Number> = new Vector.<Number>();
			var commands:Vector.<int> = new Vector.<int>();
			var divNum:uint = 5;

			points.push(mouseX,mouseY);
			commands.push(1);
		
			for (var p:uint = 0; p < dotNum-2; p++) {
				for (var d:uint = 1; d < divNum; d++) {
					var div: Number = 1 / divNum * d;
					var cx:Number;
					var cy:Number;
					if (p == 0) {
						cx = catmullRom( dots[p].x, dots[p].x, dots[p+1].x, dots[p+2].x, div);
						cy = catmullRom( dots[p].y, dots[p].y, dots[p+1].y, dots[p+2].y, div);
					} else if (p == dotNum-1) {
						cx = catmullRom( dots[p-1].x, dots[p].x, dots[p+1].x, dots[p+1].x, div);
						cy = catmullRom( dots[p-1].y, dots[p].y, dots[p+1].y, dots[p+1].y, div);
					} else {
						cx = catmullRom( dots[p-1].x, dots[p].x, dots[p+1].x, dots[p+2].x, div);
						cy = catmullRom( dots[p-1].y, dots[p].y, dots[p+1].y, dots[p+2].y, div);
					} 
					points.push(cx, cy);
					commands.push(2);
				}
				// 末尾の点
				points.push(dots[p+1].x, dots[p+1].y);
				commands.push(2);
			}
			graphics.lineStyle(1,0x000000,0.7);
			graphics.drawPath(commands, points);
			
		}
		
		public function catmullRom( x0:Number, x1:Number, x2:Number, x3:Number, t:Number ):Number{
			var v0:Number = (x2 - x0) / 2.0;    
			var v1:Number = (x3 - x1) / 2.0;    
			var t2:Number = t * t;
			var t3:Number = t2 * t;
			return ( 2.0 * x1 - 2.0 * x2 + v0 + v1 ) * t3 + ( -3.0 * x1 + 3.0 * x2 - 2.0 * v0 - v1 ) * t2 + v0 * t + x1;
			
		}
	}
}

import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
class Dot extends Sprite {
	public var target:Dot;
	private var dLimit:Number = 15;
	private var mRatio:Number = 0.75;
	private var dSpeed:Number = 0;	// ここに数値を入れると垂れ下がる
	public function Dot(nColor:uint=0xff0000, nSize:Number=10):void {
		//graphics.beginFill(nColor);
		//graphics.drawCircle(0,0,nSize);
		addEventListener(Event.ENTER_FRAME, xMove);
	}
	private function xMove(e:Event):void {
		y+=dSpeed;
		if (target == null) {
			x = stage.mouseX;
			y = stage.mouseY;
		} else {
			var tP:Point = new Point(target.x, target.y);
			var cP:Point = new Point(x, y);
			var dist:Number = Point.distance(tP,cP);
			if (dist > dLimit) {
				var dX:Number = target.x - x;
				var dY:Number = target.y - y;
				var rad:Number = Math.atan2(dX,dY);
				dist = (dist-dLimit)*mRatio;
				x += Math.sin(rad) * dist;
				y += Math.cos(rad) * dist;
			}
		}
	}
}