spring
以前見た4gamerの記事(http://www.4gamer.net/games/105/G010549/20100903012/)を思い出して作ってみた。
一番上しかドラッグがうまくいかないことに気づいたけど、直すのが面倒・・・
↓を参考に作りました。
http://wonderfl.net/c/doix
/**
* Copyright aaharu ( http://wonderfl.net/user/aaharu )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9RYg
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends Sprite
{
private const RAW:uint = 4;
private const COLUMN:uint = 5;
private const RAW_SPAN:Number = 50;
private const COLUMN_SPAN:Number = 60;
private const SPRING:Number = 0.05;
private const FRICTION:Number = 0.9;
private var _vector:Vector.<Vector.<Ball>> = new Vector.<Vector.<Ball>>();
public function Main()
{
for(var i:uint = 0; i < RAW; i++)
{
var vector:Vector.<Ball> = new Vector.<Ball>();
for(var j:uint = 0; j < COLUMN; j++)
{
var ball:Ball = new Ball();
ball.x = 80 + RAW_SPAN * i;
ball.y = 80 + COLUMN_SPAN * j;
ball.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addChild(ball);
vector.push(ball);
}
_vector.push(vector);
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
for(var i:uint = 0; i < RAW; i++)
for(var j:uint = 0; j < COLUMN-1; j++)
moveTo(_vector[i][j+1], _vector[i][j]);
for(i = 0; i < RAW-1; i++)
for(j = 0; j < COLUMN; j++)
{
if(!_vector[i][j].drag)
springTo(_vector[i][j], _vector[i+1][j]);
if(!_vector[i+1][j].drag)
springTo(_vector[i+1][j], _vector[i][j]);
}
for(i = 0; i < RAW; i++)
for(j = 0; j < COLUMN; j++)
{
_vector[i][j].x += _vector[i][j].vx;
_vector[i][j].y += _vector[i][j].vy;
}
graphics.clear();
graphics.lineStyle(1, 0x0000ff);
for(i = 0; i < RAW; i++)
{
graphics.moveTo(_vector[i][0].x, _vector[i][0].y);
for(j = 1; j < COLUMN; j++)
graphics.lineTo(_vector[i][j].x, _vector[i][j].y);
}
graphics.lineStyle(1, 0xff0000);
for(i = 0; i < COLUMN; i++)
{
graphics.moveTo(_vector[0][i].x, _vector[0][i].y);
for(j = 1; j < RAW; j++)
graphics.lineTo(_vector[j][i].x, _vector[j][i].y);
}
}
private function moveTo(ball:Ball, target:Ball):void
{
var targetX:Number = target.x;
var targetY:Number = target.y + COLUMN_SPAN;
ball.vx = targetX - ball.x;
ball.vy = targetY - ball.y;
}
private function springTo(ballA:Ball, ballB:Ball):void
{
var dx:Number = ballB.x - ballA.x;
var dy:Number = ballB.y - ballA.y;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = ballB.x - Math.cos(angle) * RAW_SPAN;
var targetY:Number = ballB.y - Math.sin(angle) * RAW_SPAN;
ballA.vx += (targetX - ballA.x) * SPRING;
ballA.vy += (targetY - ballA.y) * SPRING;
ballA.vx *= FRICTION;
ballA.vy *= FRICTION;
}
private function onMouseDown(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
event.target.startDrag();
for(var i:uint = 0; i < RAW; i++)
for(var j:uint = 0; j < COLUMN; j++)
if(event.target == _vector[i][j])
{
_vector[i][j].drag = true;
// 2重ループ抜けたいNE!
break;
}
}
private function onMouseUp(event:MouseEvent):void
{
for(var i:uint = 0; i < RAW; i++)
for(var j:uint = 0; j < COLUMN; j++)
{
_vector[i][j].stopDrag();
_vector[i][j].drag = false;
}
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
}
import flash.display.Sprite;
class Ball extends Sprite
{
private var _radius:Number;
private var _color:uint;
private var _vx:Number = 0;
private var _vy:Number = 0;
private var _drag:Boolean = false;
public function get radius():Number
{
return _radius;
}
public function get color():Number
{
return _color;
}
public function get vx():Number
{
return _vx;
}
public function set vx(v:Number):void
{
_vx = v;
}
public function get vy():Number
{
return _vy;
}
public function set vy(v:Number):void
{
_vy = v;
}
public function get drag():Boolean
{
return _drag;
}
public function set drag(bool:Boolean):void
{
_drag = bool;
}
public function Ball(radius:Number = 10, color:uint = 0)
{
_radius = radius;
_color = color;
buttonMode = true;
useHandCursor = true;
graphics.beginFill(_color);
graphics.drawCircle(0, 0, _radius);
graphics.endFill();
}
}