forked from: Orbit 1.5 (added prediction)
/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/s7SW
*/
// forked from Thy's Orbit 1.5
// forked from Thy's Orbit
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author Thi
*/
public class Main extends Sprite
{
private var
sizeMin:Number = 1,
sizeMax:Number = 100,
adding:Boolean = true,
count:int = 5,
predictions:int = 20; // also change line 323
private var // size
W:Number = 465,
H:Number = 465,
CX:Number = W>>1,
CY:Number = H>>1;
private var // layers
layer0:Sprite, layer1:Sprite, layer2:Sprite;
private var // background
back:Sprite,
bitmap:Bitmap,
data:BitmapData;
private var
predShape:Shape = new Shape();
private var // temp
g:Graphics,
s:Sprite,
t:TextField,
f:TextFormat;
private var // mouse states
down:Boolean,
move:Boolean,
up:Boolean,
X:Number, Y:Number;
private var // corpse vars
circles:Vector.<Circle>,
length:int;
private var // effect
B:Bitmap,
D:BitmapData,
RECT:Rectangle,
COL:ColorTransform;
// init
public function Main():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// init layers
layer0 = new Sprite();
layer1 = new Sprite();
layer2 = new Sprite();
stage.addChild(layer0);
stage.addChild(layer1);
stage.addChild(layer2);
// effect init
D = new BitmapData(W,H,true,0xFFFFFF);
B = new Bitmap(D, "auto", true);
RECT = D.rect;
COL = new ColorTransform(1, 1, 1, .9);
layer0.addChild(predShape);
layer0.addChild(B);
// init circles
circles = new Vector.<Circle>();
// Listeners
stage.addEventListener(MouseEvent.MOUSE_DOWN, Down); // create an object
stage.addEventListener(MouseEvent.MOUSE_UP, Up); // release an object
stage.addEventListener(Event.ENTER_FRAME, ef); // update (each frame)
}
// Listener for create an new Object
private function Down(e:MouseEvent):void
{
down = true
count = 5;
stage.addEventListener(MouseEvent.MOUSE_MOVE, Move) // change object proprieties
// crate an Objeto
var c:Circle = new Circle();
circles.push(c);
// init objt proprieties
c.x = c.pos[0] = mouseX;
c.y = c.pos[1] = mouseY;
}
private function Move(e:MouseEvent):void
{
move = true;
var c:Circle = circles[length];
c.vx = c.vel[0] = (mouseX - c.x) * .1;
c.vy = c.vel[1] = (mouseY - c.y) * .1;
}
private function Up(e:MouseEvent):void
{
up = true;
if (down)
{
down = false;
++length;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, Move);
}
}
private function ef(e:Event):void
{
// loops & draw circles.
circlesUpdate();
// draw predictions
if (length > 0 || down) drawPredictions();
// circle creating dynamics
if(!down || --count > 0) return;
var c:Circle = circles[length];
var dx:Number = c.x - mouseX, dy:Number = c.y - mouseY;
var d:Number = Math.sqrt(dx * dx + dy * dy);
if (d < 4)
{
if (adding)
{
if (++c.mass > sizeMax)
{
adding = false;
}
} else
{
if (--c.mass < sizeMin)
{
adding = true;
}
}
c.resize();
}
D.copyPixels(c.data, c.rect, c.point, null, null, true);
}
private function circlesUpdate():void
{
var i:int = -1, j:int;
var c1:Circle, c2:Circle;
var d:Number, d2:Number, dx:Number, dy:Number;
var f:Number;
var cos:Number, sin:Number, multiplier:Number;
var vx:Number, vy:Number;
D.lock();
while(++i < length)
{
c1 = circles[i];
j = i;
while(++j < length)
{
c2 = circles[j];
dx = c1.x - c2.x;
dy = c1.y - c2.y;
d2 = dx * dx + dy * dy;
d = Math.sqrt(d2);
if (d <= c1.r + c2.r) continue;
cos = dx / d;
sin = dy / d;
// gravity
f = (c1.mass + c2.mass) / d2;
c1.vx -= f / c1.mass * cos;
c1.vy -= f / c1.mass * sin;
c2.vx += f / c2.mass * cos;
c2.vy += f / c2.mass * sin;
}
c1.x += c1.vx;
c1.y += c1.vy;
c1.point.x = c1.x - c1.r;
c1.point.y = c1.y - c1.r;
c1.pos[0] = c1.x;
c1.pos[1] = c1.y;
c1.vel[0] = c1.vx;
c1.vel[1] = c1.vy;
D.copyPixels(c1.data, c1.rect, c1.point, null, null, true);
}
D.colorTransform(RECT, COL);
D.unlock();
}
private function drawPredictions():void
{
var i:int = -1, j:int, k:int = -1, l:int = predictions -1;
var c1:Circle, c2:Circle;
var d:Number, d2:Number, dx:Number, dy:Number;
var f:Number;
var cos:Number, sin:Number, multiplier:Number;
var vx:Number, vy:Number;
var k2:int, len:int = down? length +1 : length;
var xOld:Number, yOld:Number, xNew:Number, yNew:Number;
var g:Graphics = predShape.graphics;
g.clear();
g.lineStyle(.5);
while (++k < l)
{
k2 = k << 1;
i = -1;
while(++i < len)
{
c1 = circles[i];
j = i;
while(++j < len)
{
c2 = circles[j];
dx = c1.pos[k2] - c2.pos[k2];
dy = c1.pos[k2+1] - c2.pos[k2+1];
d2 = dx * dx + dy * dy;
d = Math.sqrt(d2);
if (d <= c1.r + c2.r) continue;
cos = dx / d;
sin = dy / d;
// gravity
f = (c1.mass + c2.mass) / d2;
c1.vel[k2] -= f / c1.mass * cos;
c1.vel[k2+1] -= f / c1.mass * sin;
c2.vel[k2] += f / c2.mass * cos;
c2.vel[k2+1] += f / c2.mass * sin;
}
c1.pos[k2 + 2] = c1.pos[k2] + c1.vel[k2];
c1.pos[k2 + 3] = c1.pos[k2 + 1] + c1.vel[k2 + 1];
c1.vel[k2 + 2] = c1.vel[k2];
c1.vel[k2 + 3] = c1.vel[k2 + 1];
}
}
i = -1; ++l;
while (++i < len)
{
c1 = circles[i];
k = 0;
g.moveTo(xOld = c1.pos[0], yOld = c1.pos[1])
while (++k < l)
{
xNew = c1.pos[(k << 1)];
yNew = c1.pos[(k << 1) + 1];
dx = xNew - xOld;
dy = yNew - yOld;
d = dx * dx + dy * dy;
if (d > .2)
{
g.lineTo(xNew, yNew);
}
xOld = xNew;
yOld = yNew;
}
}
}
}
}
import flash.display.Shape;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
/**
* ...
* @author Thi
*/
class Circle
{
public var // proprieties
x:Number, y:Number,
vx:Number = 0, vy:Number = 0, v:Number = 0;
public var
mass:Number = 1, // arbitrary
r:Number = (3 * mass / (Math.PI<<2)) ^ (1/3);
public var
color:uint = uint((Math.random()*0xFF)<<16 | (Math.random()*0xFF)<<8 | Math.random()*0xFF),
data:BitmapData,
rect:Rectangle = new Rectangle(0,0,r<<1,r<<1),
point:Point = new Point(0, 0);
public var
pos:Vector.<Number> = new Vector.<Number>(20 << 1),
vel:Vector.<Number> = new Vector.<Number>(20 << 1);
public function Circle():void
{
resize();
}
public function resize():void
{
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.beginFill(color);
r = (3 * mass / (Math.PI << 2)) ^ (1 / 3);
if(r<1) r=1;
// mass = Math.PI << 2 / 3 * r * r * r;
g.drawCircle(r, r, r);
g.endFill();
data = new BitmapData(r << 1, r << 1, true, 0xFFFFFF);
rect.width = r << 1;
rect.height = r << 1;
data.draw(shape);
point.x = x - r;
point.y = y - r;
shape = null;
g = null;
}
}