マウスに毛が絡まった
単純にlineToで繋げると直線っぽくなってしまうのを
* CatmullRom曲線を使ってそれらしく
* curveToで描けば良さそうなものなんですが…
/*
* 単純に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;
}
}
}
}