Satellite Simulator

The infinite expanse of space on your computer! Click to place the black hole.

Demo

Document Class:


package com.elegantactionscript.fxpression09 {
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.display.Graphics;
	import flash.events.MouseEvent;
	public class CursorGravity extends Sprite {
		
		public static const G:Number = 0.0000000000667;
		
		public static var meter:Number;
		public static var cursorMass:Number; // kg
		public static var massMultiplier:Number;
		public static var blackHole:Shape;
		
		public function CursorGravity():void {
			meter = 5;
			cursorMass = 100000;
			massMultiplier = 700;
			
			blackHole = new Shape();
			blackHole.x = stage.stageWidth / 2
			blackHole.y = stage.stageHeight / 2;
			var g:Graphics = blackHole.graphics;
			with (g) {
				lineStyle(1, 0xffff00, 0.5);
				beginFill(0x000000);
				drawCircle(0, 0, 10);
			}
			addChild(blackHole);
			stage.frameRate = 30;
			
			var satellites:Array = [[100, 30, 60, -0.5, 1], [350, 430, 40, 1, -1], [20, 110, 30, 0, 1], [150, 20, 20, 1, 0], [200, 200, 10, 0.2, -0.5], [250, 70, 25, -0.8, 0.2], [300, 300, 5, 0, -0.2], [275, 150, 10, -0.5, 0]];
			var l:int = satellites.length;
			for (var i:uint = 0; i<l; i++) {
				var satellite:Satellite = new Satellite(satellites*[2]);
				satellite.x = satellites*[0]
				satellite.y = satellites*[1]
				satellite.xSpeed = satellites*[3];
				satellite.ySpeed = satellites*[4];
				addChild(satellite);
				satellite.setup();
			}
			stage.addEventListener(MouseEvent.CLICK, placeBlackHole, false, 0, true);
		}
		
		private function placeBlackHole(evt:MouseEvent):void {
			blackHole.x = evt.stageX;
			blackHole.y = evt.stageY;
		}
	}
}

Satellite:


package com.elegantactionscript.fxpression09 {
	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.events.Event;
	public class Satellite extends Sprite {
		
		private var radius:Number;
		private var mass:Number;
		public var xSpeed:Number;
		public var ySpeed:Number;
		private var xAcc:Number;
		private var yAcc:Number;
		
		public function Satellite(radius:Number):void {
			this.radius = radius;
			mass = (Math.PI * radius * radius) / 2  * CursorGravity.massMultiplier;
			xSpeed = 0;
			ySpeed = 0;
			xAcc = 0;
			yAcc = 0;
			
			var g:Graphics = this.graphics;
			with (g) {
				lineStyle(2, 0xffffff, 0.5);
				beginFill(0x000022);
				drawCircle(0, 0, radius);
			}
		}
		
		public function setup():void {
			stage.addEventListener(Event.ENTER_FRAME, updateScreen, false, 0, true);
		}
		
		private function updateScreen(evt:Event):void {
			var gravityForce = (CursorGravity.G * CursorGravity.cursorMass * this.mass) / (getDistance());
			var cursorAngle = Math.atan2( (y - CursorGravity.blackHole.y), (x - CursorGravity.blackHole.x) );
			xAcc = -gravityForce * Math.cos(cursorAngle);
			yAcc = -gravityForce * Math.sin(cursorAngle);
			xSpeed += xAcc;
			ySpeed += yAcc;
			x += xSpeed;
			y += ySpeed;
		}
		
		private function getDistance():Number {
			return Math.sqrt( (x - CursorGravity.blackHole.x) * (x - CursorGravity.blackHole.x) + (y - CursorGravity.blackHole.y) * (y - CursorGravity.blackHole.y) ) * CursorGravity.meter;
		}
	}
}

It’s either calming and serene or very slow, depending on how you look at it. It think it is the epitome of tranquility…