Orbit 1.5
@author Thi
// forked from Thy's Orbit
// collision ref: http://www.emanueleferonato.com/2008/06/07/managing-multiple-balls-collisions-with-flash-as3-version/
/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pXfr
*/
// 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.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;
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 // 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(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 = mouseX;
c.y = mouseY;
}
private function Move(e:MouseEvent):void
{
move = true;
var c:Circle = circles[length];
c.vx = (mouseX - c.x) * .1;
c.vy = (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();
// circle creating dynamics
if(!down) return;
if (--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;
// corners
/*
if (c1.x < c1.r) c1.x = c1.r, c1.vx = -c1.vx;
if (c1.x > W - c1.r) c1.x = W - c1.r, c1.vx = -c1.vx;
if (c1.y < c1.r) c1.y = c1.r, c1.vy = -c1.vy;
if (c1.y > H - c1.r) c1.y = H - c1.r, c1.vy = -c1.vy;
*/
c1.point.x = c1.x - c1.r;
c1.point.y = c1.y - c1.r;
D.copyPixels(c1.data, c1.rect, c1.point, null, null, true);
}
D.colorTransform(RECT, COL);
D.unlock();
}
}
}
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 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;
}
}