forked from: 【AS100本ノック】3回目:ヒモ
AS100本ノック
* 3回目のお題は「ヒモ」
* あなたなりの「ヒモ」を表現してください。
* --
* ギブです。時間がとれませんでした。
* D&Dで新体操のリボン的な動きを目指してました。
* --
* 参考
* http://www.friendsofed.com/downloads.html
/**
* 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;
}
}
}