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: 【AS100本ノック】3回目:ヒモ

AS100本ノック
* 3回目のお題は「ヒモ」
* あなたなりの「ヒモ」を表現してください。
* --
* ギブです。時間がとれませんでした。
* D&Dで新体操のリボン的な動きを目指してました。
* --
* 参考
* http://www.friendsofed.com/downloads.html
Get Adobe Flash player
by mex_ichikawa 08 Feb 2010
    Embed
/**
 * Copyright mex_ichikawa ( http://wonderfl.net/user/mex_ichikawa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/yzbh
 */

/**
 * AS100本ノック
 * 3回目のお題は「ヒモ」
 * あなたなりの「ヒモ」を表現してください。
 * --
 * ギブです。時間がとれませんでした。
 * D&Dで新体操のリボン的な動きを目指してました。
 * --
 * 参考
 * http://www.friendsofed.com/downloads.html
 */
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	[SWF(width=465, height=465, backgroundColor=0x000000, frameRate=30)]
	public class Line extends Sprite
	{
		private static const CELL_RADIUS:uint = 3;
		private static const POINT_MAX:uint = 20;
		private var _spring:Number = 0.05;
		private var _friction:Number = 0.95;
		private var _points:Vector.<Pos>;
		private var _weight:Weight;
		public function Line()
		{
			init();
		}
		private function init():void
		{
			var point:Pos;
			_points = new Vector.<Pos>;
			_weight = new Weight(10);
			
			for(var i:uint=0,max:uint=POINT_MAX; i<max; i++)
			{
				point = new Pos();
				point.x = stage.stageWidth / 2;
				point.y = i * CELL_RADIUS;
				if(i==0) point.isMove = false;
				_points.push(point);
			}
			_weight.x = point.x;
			_weight.y = point.y;
			addChild(_weight);
			
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			_weight.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		}
		private function enterFrameHandler(event:Event):void
		{
			graphics.clear();
			graphics.lineStyle(1, 0xFFFFFFFF);
			
			_points[_points.length-1].x = _weight.x;
			_points[_points.length-1].y = _weight.y;
			
			var max:uint = _points.length;
			for(var i:uint=0; i<max; i++)
			{
				if(i-1 >= 0 && _points[i].isMove)
				{
					springTo(_points[i], _points[i-1]);
				}
				if(i+1 < max  && _points[i].isMove)
				{
					springTo(_points[i], _points[i+1]);
				}
			}
			
			if(!_weight.isDrag)
			{
				_weight.x = _points[_points.length-1].x;
				_weight.y = _points[_points.length-1].y;
			}
			
			for(i=0; i<max-1; i++)
			{
				if(i==0)
				{
					graphics.moveTo(_points[i].x, _points[i].y);
				}
				if(i+1 < max)
				{
					if(i-1 >= 0 && i+2 < max)
					{
						var p:Point = getCurvePoint(
							new Point(_points[i-1].x, _points[i-1].y),
							new Point(_points[i].x, _points[i].y),
							new Point(_points[i+1].x, _points[i+1].y),
							new Point(_points[i+2].x, _points[i+2].y)
						);
						graphics.curveTo(p.x, p.y, _points[i+1].x, _points[i+1].y);
					}
					else
					{
						graphics.lineTo(_points[i+1].x, _points[i+1].y);
					}
				}
			}
		}
		private function getCurvePoint(p1:Point, p2:Point, p3:Point, p4:Point):Point
		{
			var pp1:Point = Point.interpolate(p1, p2, 0.5);
			pp1 = pp1.subtract(p1);
			pp1 = p2.add(pp1);
			
			var pp2:Point = Point.interpolate(p3, p4, 0.5);
			pp2 = pp2.subtract(p4);
			pp2 = p3.add(pp2);
			
			return Point.interpolate(pp1, pp2, 0.5);
		}
		private function springTo(p1:Pos, p2:Pos):void
		{
			var dx:Number = p2.x - p1.x;
			var dy:Number = p2.y - p1.y;
			var angle:Number = Math.atan2(dy, dx);
			var targetX:Number = p2.x - Math.cos(angle) * CELL_RADIUS;
			var targetY:Number = p2.y - Math.sin(angle) * CELL_RADIUS;
			p1.vx += (targetX - p1.x) * _spring;
			p1.vy += (targetY - p1.y) * _spring;
			p1.vx *= _friction;
			p1.vy *= _friction;
			p1.x += p1.vx;
			p1.y += p1.vy;
		}
		private function mouseDownHandler(event:MouseEvent):void
		{
			_weight.startDrag();
			_weight.isDrag = true;
		}
		private function mouseUpHandler(event:MouseEvent):void
		{
			_weight.stopDrag();
			_weight.isDrag = false;
		}
	}
}
class Pos {
	public var vx:Number = 0;
	public var vy:Number = 0;
	public var x:Number = 0;
	public var y:Number = 0;
	public var isMove:Boolean = true;
	public function Pos() {
	}
}
import flash.display.Sprite;
import flash.events.Event;
class Weight extends Sprite {
	public var isDrag:Boolean = false;
	private var _radius:Number;
	private var _color:uint;
	private var _vx:Number = 0;
	private var _vy:Number = 0;
	private var _bounce:Number = -0.01;
	private var _gravity:Number = 0.05;
	private var _oldX:Number;
	private var _oldY:Number;
	
	public function Weight(radius:Number=40, color:uint=0xFFFFFF) {
		_radius = radius;
		_color = color;
		init();
	}
	public function init():void {
		graphics.beginFill(_color);
		graphics.drawCircle(0, 0, _radius);
		graphics.endFill();
		
		addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		
	}
	private function enterFrameHandler(event:Event):void
	{
		if(!isDrag)
		{
			_vy += _gravity;
			x += _vx;
			y += _vy;
			var left:Number = 0;
			var right:Number = stage.stageWidth;
			var top:Number = 0;
			var bottom:Number = stage.stageHeight;
			
			if(x + _radius > right)
			{
				x = right - _radius;
				_vx *= _bounce;
			}
			else if(x - _radius < left)
			{
				x = left + _radius;
				_vx *= _bounce;
			}
			if(y + _radius > bottom)
			{
				y = bottom - _radius;
				_vy *= _bounce;
			}
			else if(y - _radius < top)
			{
				y = top + _radius;
				_vy *= _bounce;
			}
		}
		else
		{
			_vx = 0;
			_vy = 0;
		}
	}
}