カエルの卵3
ちょっとスムーズに伸び縮みするように
...
@author tkinjo
/**
* Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/Anzs
*/
// forked from tkinjo's カエルの卵2
// forked from tkinjo's カエルの卵
// forked from tkinjo's ひもっぽい何か
// forked from tkinjo's 点の追従
package
{
/**
* ちょっとスムーズに伸び縮みするように
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
[SWF(width="465", height="465", frameRate="60", backgroundColor="0xeeeeff")]
/**
* ...
* @author tkinjo
*/
public class Main extends Sprite {
// 点の数
private const dotNum:int = 100;
// 摩擦係数
private const friction:Number = 0.1;
// 点の半径
private const dotRadius:uint = 1;
// 点と点との距離
private const minDistance:uint = 5;
private const maxDistance:uint = 10;
// 点の配列
private var dots:Array = new Array();
/**
* コンストラクタ
*/
public function Main() {
createDots();
// フレームごとにループ
addEventListener(Event.ENTER_FRAME, function( event:Event ):void {
calc();
draw();
} );
}
/**
* 点の作成
*/
private function createDots():void {
for ( var i:uint = 0; i < dotNum; i++) {
var dot:Point = new Point( mouseX, mouseY );
dots.push( dot );
}
}
/** --------------------------------------------------
* 計算
*/
private function calc():void {
for ( var i:uint = 0; i < dotNum; i++ ) {
// 座標の算出
if ( i == 0 ) {
dots[ i ].x = mouseX;
dots[ i ].y = mouseY;
} else {
// 距離と角度の算出
var dx:Number = dots[ i ].x - dots[ i - 1 ].x;
var dy:Number = dots[ i ].y - dots[ i - 1 ].y;
var distance:Number = Math.sqrt( dx * dx + dy * dy );
var angle:Number = Math.atan2( dy, dx );
// 速度の算出
var vx:Number = ( distance - minDistance ) * -Math.cos( angle ) * friction;
var vy:Number = ( distance - minDistance ) * -Math.sin( angle ) * friction;
// 座標の算出
dots[ i ].x += vx;
dots[ i ].y += vy;
// 距離の調整
// 距離と角度の再算出
dx = dots[ i ].x - dots[ i - 1 ].x;
dy = dots[ i ].y - dots[ i - 1 ].y;
distance = Math.sqrt( dx * dx + dy * dy );
angle = Math.atan2( dy, dx );
// 一定の距離をあける
if( distance < minDistance ) {
dots[ i ].x = dots[ i - 1 ].x + minDistance * Math.cos( angle );
dots[ i ].y = dots[ i - 1 ].y + minDistance * Math.sin( angle );
// 一定の距離以上離れさせない
} else if ( distance > maxDistance ) {
dots[ i ].x = dots[ i - 1 ].x + maxDistance * Math.cos( angle );
dots[ i ].y = dots[ i - 1 ].y + maxDistance * Math.sin( angle );
}
}
}
}
/** --------------------------------------------------
* 描画
*/
private function draw():void {
graphics.clear();
graphics.beginFill( 0 );
for ( var i:uint = 0; i < dotNum; i++ ) {
if( i == 0 )
graphics.drawCircle( dots[ i ].x, dots[ i ].y, dotRadius );
else {
var angle:Number = Math.atan2( dots[ i ].y - dots[ i - 1 ].y, dots[ i ].x - dots[ i - 1 ].x );
if ( i % 2 == 0 )
angle += ( 90 / 360 ) * ( 2 * Math.PI );
else
angle -= ( 90 / 360 ) * ( 2 * Math.PI );
graphics.drawCircle( dots[ i ].x + dotRadius * Math.cos( angle ), dots[ i ].y + dotRadius * Math.sin( angle ), dotRadius );
}
}
graphics.endFill();
// -----
graphics.lineStyle( 1, 0xcccccc );
graphics.moveTo( dots[ 0 ].x, dots[ 0 ].y );
for ( i = 1; i < dotNum; i++ ) {
angle = Math.atan2( dots[ i ].y - dots[ i - 1 ].y, dots[ i ].x - dots[ i - 1 ].x ) + ( 90 / 360 ) * ( 2 * Math.PI );
graphics.lineTo( dots[ i ].x + ( dotRadius * 4 ) * Math.cos( angle ), dots[ i ].y + ( dotRadius * 4 ) * Math.sin( angle ) );
}
for ( i = dotNum - 1; i > 0; i-- ) {
angle = Math.atan2( dots[ i ].y - dots[ i - 1 ].y, dots[ i ].x - dots[ i - 1 ].x ) - ( 90 / 360 ) * ( 2 * Math.PI );
graphics.lineTo( dots[ i ].x + ( dotRadius * 4 ) * Math.cos( angle ), dots[ i ].y + ( dotRadius * 4 ) * Math.sin( angle ) );
}
graphics.lineTo( dots[ 0 ].x, dots[ 0 ].y );
}
}
}