illuminated gravitation (enhanced performance)
/**
* Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zNeg
*/
// forked from leichtgewicht's illuminated gravitation
// forked from leichtgewicht's gravitation (cleaned and uses vectors)
// forked from ganad's gravitation
package
{
import flash.display.StageQuality;
import flash.display.IGraphicsData;
import flash.events.MouseEvent;
import flash.display.Shape;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.display.Sprite;
/**
* ...
* @author ganad
* @author Martin Heidegger
*/
public class Main extends Sprite
{
private static const AMOUNT_PLANETS: int = 250;
private static const G: Number = 5.0;
private var _sun:Sun;
private var _planets:Vector.<Planet> = new Vector.<Planet>();
private var _planetsLayer: Shape;
private var _data: Vector.<IGraphicsData>;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 40;
stage.quality = StageQuality.BEST;
createBackground();
createPlanets(AMOUNT_PLANETS);
createSun();
_data = combineDrawData(_planets);
addEventListener(Event.ENTER_FRAME, applyGravity);
}
private function createBackground(): void {
stage.addEventListener(Event.RESIZE, drawBackground);
drawBackground();
}
private function drawBackground(e:Event=null): void {
graphics.clear();
graphics.beginFill(0x000000,1);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
}
private function createPlanets(amount:int):void {
addChild( _planetsLayer = new Shape() );
for( var i: int = 0; i<amount; ++i) {
addPlanet(
0x181818,
0xFFFFFF,
randomBetween(1,40),
randomBetween(8,9),
randomBetween(-8,8),
randomBetween(250,280),
randomBetween(90,160)
)
}
/*
addPlanet(1, 10, -10, 275, 150);
addPlanet(1, 7, 3, 275, 150);
addPlanet(40, 5, 5, 275, 100);
addPlanet(20, 10, 0, 275, 150);
*/
}
private function combineDrawData(planets: Vector.<Planet>): Vector.<IGraphicsData> {
var data: Vector.<IGraphicsData> = new Vector.<IGraphicsData>(calculateDataLength(planets));
var dataNo: int = 0;
for each(var planet: Planet in planets ) {
for each( var part: IGraphicsData in planet.line.data ) {
data[dataNo] = part;
dataNo++;
}
}
return data;
}
private function calculateDataLength(planets: Vector.<Planet>): int {
var totalCount: int = 0;
for each( var planet: Planet in planets ) {
totalCount += planet.line.data.length;
}
return totalCount;
}
private function randomBetween(from: Number, to: Number): Number {
return from + Math.random() * (to-from);
}
private function addPlanet(minColor: int, maxColor: int, mass: int, vx:Number, vy:Number, x:Number, y:Number): void {
_planets.push(new Planet(minColor, maxColor, mass, vx, vy, x, y));
}
private function createSun(): void {
var sun: Sun = new Sun(1000, 0, 0, 275, 200)
addChild(sun.ball);
_sun = sun;
}
private function applyGravity(e:Event = null):void {
for (var i:int = 0; i < _planets.length; i++) {
_planets[i].applyGravity(_sun, G);
}
paint();
}
private function paint(): void {
_planetsLayer.graphics.clear();
_planetsLayer.graphics.drawGraphicsData(_data);
}
}
}
import flash.display.GraphicsGradientFill;
import flash.display.IGraphicsPath;
import flash.display.GraphicsPathCommand;
import flash.display.GraphicsSolidFill;
import flash.display.JointStyle;
import flash.display.CapsStyle;
import flash.display.LineScaleMode;
import flash.display.GraphicsPath;
import flash.display.GraphicsStroke;
import flash.display.Shape;
import flash.display.IGraphicsData;
class StellarObject
{
public var vx:Number;
public var vy:Number;
public var x:Number = 0;
public var y:Number = 0;
public var mass:int;
public function StellarObject(mass:int=50, vx:Number=40,vy:Number=0,x:Number=0,y:Number=0): void
{
this.mass = mass;
this.vx = vx;
this.vy = vy;
this.x = x;
this.y = y;
}
}
class Sun extends StellarObject
{
private static const SUN_COLOR: int = 0x181818;
public var ball: Shape;
public function Sun(mass:int=50, vx:Number=40,vy:Number=0,x:Number=0,y:Number=0): void
{
super(mass, vx, vy, x, y);
ball = new Shape();
moveTo(x, y);
}
public function moveTo(x: Number, y: Number): void {
this.x = x;
this.y = y;
ball.graphics.clear();
ball.graphics.beginFill(SUN_COLOR, 1);
ball.graphics.drawCircle(x, y, 10);
ball.graphics.endFill();
}
}
/**
* ...
* @author ganad
*/
class Planet extends StellarObject
{
public var line:MovingLine;
public function Planet(minColor: int, maxColor: int, mass:int, vx:Number, vy:Number, x:Number, y:Number) :void
{
super(mass, vx, vy, x, y);
line = new MovingLine(minColor, maxColor, x, y);
}
public function applyGravity(target: StellarObject, gravity: Number): void
{
var dx:Number = target.x-this.x;
var dy:Number = target.y-this.y;
var dist:Number = dx * dx + dy * dy;
var angle:Number = Math.atan2(dy, dx);
var F:Number = gravity * target.mass / dist;
var vx:Number = F * Math.cos(angle);
var vy:Number = F * Math.sin(angle);
this.vx += vx;
this.vy += vy;
this.x += this.vx;
this.y += this.vy;
line.update(this.x, this.y, F / 1.8 );
}
}
class MovingLine extends Shape {
private var _data: Vector.<IGraphicsData>;
private var _strokeFills: Vector.<GraphicsSolidFill>;
private var _paths: Vector.<GraphicsPath>;
private var _hasMoved: Boolean = false;
private var _minRGB: RGB;
private var _maxRGB: RGB;
public function MovingLine(minColor: int, maxColor: int, x: Number, y: Number) {
_minRGB = new RGB(minColor);
_maxRGB = new RGB(maxColor);
createData(minColor, x, y, 12);
}
public function get data(): Vector.<IGraphicsData> {
return _data;
}
private function createData(color: int, x: Number, y: Number, segments: int): void {
_paths = new Vector.<GraphicsPath>();
_data = new Vector.<IGraphicsData>();
_strokeFills = new Vector.<GraphicsSolidFill>();
createFirstPath(x, y);
var alpha: Number = 0.0;
var alphaDecay: Number = 1.0/segments;
for( var segmentNo: int = 0, dataNo: int = 1; segmentNo<segments; ++segmentNo, dataNo+=2) {
createStroke(color, alpha);
createPath(x, y);
alpha += alphaDecay;
}
}
private function createFirstPath(x: Number, y: Number): void {
createPath(x, y, GraphicsPathCommand.MOVE_TO);
}
private function createPath(x: Number, y: Number, command: int = GraphicsPathCommand.LINE_TO): void {
var path: GraphicsPath = new GraphicsPath(new Vector.<int>(1), new Vector.<Number>(2));
path.commands[0] = command;
path.data[0] = x;
path.data[1] = y;
_data.push(path);
_paths.push(path);
}
private function createStroke(color: int, alpha: Number): GraphicsStroke {
var fill: GraphicsSolidFill = new GraphicsSolidFill(color, alpha);
_strokeFills.push(fill);
var stroke: GraphicsStroke = new GraphicsStroke(1, false, LineScaleMode.NONE, CapsStyle.NONE, JointStyle.MITER, 0, fill);
_data.push(stroke);
return stroke;
}
public function update(x: Number, y: Number, strength: Number): void {
var path: GraphicsPath = dequeue();
moveLastSegment(path, x, y);
setColor(RGB.mix(_minRGB, _maxRGB, strength));
}
private function dequeue(): GraphicsPath {
for( var pathNo: int = 1; pathNo<_paths.length; ++pathNo) {
var formerPath: GraphicsPath = _paths[pathNo-1];
var lastPath: GraphicsPath = _paths[pathNo];
formerPath.data[0] = lastPath.data[0];
formerPath.data[1] = lastPath.data[1];
}
return lastPath;
}
private function moveLastSegment(lastSegment: GraphicsPath, x: Number, y: Number): void {
if( !_hasMoved ) {
lastSegment.data[0] = x;
lastSegment.data[1] = y;
_hasMoved = true;
}
lastSegment.data[0] = x;
lastSegment.data[1] = y;
}
private function setColor(color: int): void {
for each( var fill: GraphicsSolidFill in _strokeFills) {
fill.color = color;
}
}
}
class RGB {
public var r: int;
public var g: int;
public var b: int;
public static function mix(rgbA: RGB, rgbB: RGB, mix: Number): int {
if( mix > 1.0 ) mix = 1.0;
else if(mix < 0.0) mix = 0.0;
var r: int = rgbA.r + (rgbB.r-rgbA.r) * mix;
var g: int = rgbA.g + (rgbB.g-rgbA.g) * mix;
var b: int = rgbA.b + (rgbB.b-rgbA.b) * mix;
return (r << 16) | (g << 8) | b;
}
public function RGB(color: int) {
r = (color & 0xFF0000) >> 16;
g = (color & 0xFF00) >> 8;
b = color & 0xFF;
}
}
var trace: Function = Wonderfl.log;