RubberNet
ゴムでできた網。
クリックするとゆらせます。
/**
* Copyright enu ( http://wonderfl.net/user/enu )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2V76t
*/
package {
import flash.display.LineScaleMode;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
[SWF(width=465 ,height=465,backgroundColor=0xFFFFFF,frameRate=60)]
public class Main extends Sprite {
public var mNodes:Array = null;
public var mVerticalEdges:Array = null;
public var mHorizontalEdges:Array = null;
public function Main() {
mNodes = new Array( HorizontalNodeNumber );
for (var i:int = 0; i < HorizontalNodeNumber; i++) {
mNodes[ i ] = new Array( VerticalNodeNumber );
for (var j:int = 0; j < VerticalNodeNumber; j++) {
var nd : Node = new Node();
nd.x = i * NeutralDistance;
nd.y = j * NeutralDistance;
mNodes[ i ][ j ] = nd;
}
}
mVerticalEdges = new Array( HorizontalNodeNumber - 1 );
mHorizontalEdges = new Array( HorizontalNodeNumber - 1 );
for ( i = 0; i < HorizontalNodeNumber - 1; i++) {
mVerticalEdges[ i ] = new Array( VerticalNodeNumber - 1 );
mHorizontalEdges[ i ] = new Array( VerticalNodeNumber - 1 );
for ( j = 0; j<VerticalNodeNumber-1; j++) {
mVerticalEdges[ i ][ j ] = new Edge( i * NeutralDistance , j * NeutralDistance,i * NeutralDistance,(j+1) * NeutralDistance );
mHorizontalEdges[ i ][ j ] = new Edge( i * NeutralDistance , j * NeutralDistance,(i+1) * NeutralDistance,j * NeutralDistance );
addChild( mVerticalEdges[ i ][ j ] );
addChild( mHorizontalEdges[ i ][ j ] );
}
}
addEventListener(Event.ENTER_FRAME,update);
this.stage.addEventListener( MouseEvent.CLICK,onMouseClick );
}
public function update(e:Event):void {
//まずはエッジの状態を入れる
for ( var i:int = 0 ; i < HorizontalNodeNumber-1 ; ++i ) {
for ( var j:int = 0 ; j < VerticalNodeNumber - 1 ; ++j ) {
mHorizontalEdges[ i ][ j ].setNode( mNodes[ i ][ j ], mNodes[ i + 1 ][ j ]);
mVerticalEdges[ i ][ j ].setNode( mNodes[ i ][ j ], mNodes[ i ][ j + 1 ] );
}
}
//ノードを更新
//隅っこのノードは動かさない。
for ( i = 1 ; i < HorizontalNodeNumber-1 ; ++i ) {
for ( j = 1 ; j < VerticalNodeNumber-1 ; ++j ) {
mNodes[ i ][ j ].setEdgeForce(
mHorizontalEdges[ i - 1 ][ j ],
mVerticalEdges[ i ][ j - 1 ] ,
mHorizontalEdges[ i ][ j ],
mVerticalEdges[ i ][ j ] );
mNodes[ i ][ j ].update();
}
}
}
public function onMouseClick(e:MouseEvent):void {
//クリック点を中心に力をかけてやる
for ( var i:int = 1 ; i < HorizontalNodeNumber-1 ; ++i ) {
for ( var j:int = 1 ; j < VerticalNodeNumber-1 ; ++j ) {
var dx :Number = mNodes[ i ][ j ].x - mouseX;
var dy :Number = mNodes[ i ][ j ].y - mouseY;
var d : Number = Math.sqrt( dx * dx + dy * dy );
//どんぴしゃでクリックしたら動かさない
if ( d > 4 ) {
//かかる力
var fx : Number = 10000 * dx / d / d;
var fy : Number = 10000 * dy / d / d;
mNodes[ i ][ j ].setForce( fx, fy );
}
}
}
}
}
}
import flash.display.Sprite;
import flash.display.GradientType;
import flash.geom.Matrix;
const StageWidth : int = 465;
const StageHeight : int = 465;
const VerticalNodeNumber:int = 20;
const HorizontalNodeNumber:int = VerticalNodeNumber;
const NeutralDistance:Number = StageWidth / ( VerticalNodeNumber - 1 );
class Node {
private var mVelocityX : Number = 0;
private var mVelocityY : Number = 0;
private const Weight : Number = 100;
private const Size : Number = 8;
public var x : Number = 0;
public var y : Number = 0;
public function setEdgeForce( a : Edge, b: Edge, c: Edge, d: Edge ) : void {
//まず合力を得る
var forceX : Number = 0;
var forceY : Number = 0;
forceX = a.forceX + b.forceX - c.forceX - d.forceX;
forceY = a.forceY + b.forceY - c.forceY - d.forceY;
setForce( forceX, forceY + 1 ); //重力もついでにかけてやろう
}
public function setForce( fx : Number, fy: Number ) :void {
//速度更新
mVelocityX += fx / Weight;
mVelocityY += fy / Weight ;
}
public function update() : void {
//位置更新
x += mVelocityX;
y += mVelocityY;
//速度減衰
mVelocityX *= 0.95;
mVelocityY *= 0.95;
}
}
//押す力が正、ちぢもうとする力が負とする。
class Edge extends Sprite {
private var mForceX : Number = 0;
private var mForceY : Number = 0;
public function Edge( X1 : Number, Y1:Number, X2:Number , Y2 : Number ) {
this.graphics.lineStyle( 0 );
var matrix:Matrix = new Matrix();
matrix.createGradientBox( 1, 1, 0, 0, 0 );
this.graphics.lineGradientStyle( GradientType.LINEAR, [ color( X1,Y1 ), color( X2,Y2 ) ], [ 1, 1 ], [ 0, 255 ],matrix );
this.graphics.moveTo( 0, 0 );
this.graphics.lineTo( 1, 0 );
setPosition( X1, Y1, X2, Y2 );
}
private function setPosition( X1 : Number, Y1:Number, X2:Number , Y2: Number ) : void {
var xDis : Number = X2 - X1;
var yDis : Number = Y2 - Y1;
var dis : Number = Math.sqrt( xDis * xDis + yDis * yDis );
var force : Number = NeutralDistance - dis;
if ( force > 0 ) {
force = 0; //ここをコメントアウトするとバネになる
}
mForceX = force * xDis / dis;
mForceY = force * yDis / dis;
var ang : Number = 180 * Math.atan2( yDis, xDis ) / Math.PI;
this.x = X1
this.y = Y1;
this.rotation = ang;
this.scaleX = dis;
}
public function setNode( first : Node, second : Node ) : void {
setPosition( first.x, first.y, second.x, second.y );
}
public function get forceX():Number { return mForceX; }
public function get forceY():Number { return mForceY; }
private function color( X :Number , Y:Number ) : int {
//グラデーションかける.
var r : int = 0xff * X / StageWidth;
var g : int = 0xff * Y / StageHeight;
var b : int = 0xff;
return ( r * 0x010000 + g * 0x000100 + b * 0x000001 );
}
}