package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width="600", height="600", backgroundColor="#0", frameRate="30")]
public class HelioCentric extends MovieClip
{
private var firstFrame:Boolean = true;
private var earth:Planet = new Planet();
private var sun:Planet = new Planet();
private var mercury:Planet = new Planet();
private var moon:Planet = new Planet();
private var venus:Planet = new Planet();
private var mars:Planet = new Planet();
private var currentScale:Number = 0.7;
private var solSys:Sprite = new Sprite();
private var trailPlanets:Array = new Array();
private var trails:Sprite = new Sprite();
private var oldPoints:Array;
private var earthPeriod:uint = 800;
private var mercuryCentre:Planet = new Planet();
private var venusCentre:Planet = new Planet();
private var marsCentre:Planet = new Planet();
//set up planet colours, sizes, orbits
public function HelioCentric()
{
//inittrace(stage);
stage.addEventListener(MouseEvent.MOUSE_WHEEL, wheely);
var bg:Sprite = new Sprite();
bg.graphics.beginFill(0x0);
bg.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
bg.graphics.endFill();
addChild(bg);
earth.drawPlanet(0x0000ff);
earth.setLightSource(sun);
earth.drawShadow();
earth.setLabel("Earth");
solSys.addChild(earth);
moon.showTrails = true;
moon.trailColour = 0xaa00aa;
moon.drawPlanet(0xcccccc, 14);
moon.drawShadow();
moon.setLabel("The Moon");
moon.setOrbit(earth, sun, 80, 20);
solSys.addChild(moon);
trailPlanets.push(moon);
mercury.trailColour = 0xffffff;
mercury.showTrails = true;
mercury.drawPlanet(0xeecc44, 20);
mercury.drawShadow();
mercury.setLabel("Mercury");
mercuryCentre.setOrbit(earth, sun, 150, earthPeriod);
mercury.setOrbit(mercuryCentre, sun, 30, 40);
solSys.addChild(mercury);
trailPlanets.push(mercuryCentre);
trailPlanets.push(mercury);
venus.showTrails = true;
venus.trailColour = 0xffffff;
venus.drawPlanet(0xffcc99);
venus.drawShadow();
venus.setLabel("Venus");
venusCentre.setOrbit(earth, sun, 300, earthPeriod);
venus.setOrbit(venusCentre, sun, 50, 80);
solSys.addChild(venus);
trailPlanets.push(venusCentre);
trailPlanets.push(venus);
sun.showTrails = true;
sun.trailColour = 0xffffff;
sun.drawPlanet(0xffff00, 50, 0xffffff);
sun.setLabel("Sun", 0x0);
sun.setOrbit(earth, sun, 450, earthPeriod);
solSys.addChild(sun);
trailPlanets.push(sun);
mars.showTrails = true;
mars.trailColour = 0xffffff;
mars.drawPlanet(0xffaa00, 22);
mars.drawShadow();
mars.setLabel("Mars");
marsCentre.setOrbit(earth, sun, 600, earthPeriod);
mars.setOrbit(marsCentre, sun, 60, 2*earthPeriod);
solSys.addChild(mars);
trailPlanets.push(marsCentre);
trailPlanets.push(mars);
solSys.x = stage.stageWidth / 2;
solSys.y = stage.stageHeight / 2;
solSys.addChild(trails);
solSys.scaleX = currentScale;
solSys.scaleY = currentScale;
addChild(solSys);
oldPoints = new Array(trailPlanets.length);
for(var i:uint = 0; i < oldPoints.length; i++)
{
oldPoints[i] = new Point(trailPlanets[i].x, trailPlanets[i].y);
}
addEventListener(Event.ENTER_FRAME, loop);
}
//function to control zooming with the mouse wheel
public function wheely(m:MouseEvent):void
{
if (m.delta < 0)
{
//wheel down:
trace("wheel down");
var oldmx:Number = mouseX;
var oldmy:Number = mouseY;
if(currentScale > 0)
{currentScale -= 0.1;}
else{currentScale = 0;}
trace("currentScale: "+currentScale);
solSys.scaleX = currentScale;
solSys.scaleY = currentScale;
}
else if (m.delta > 0)
{
//wheel up:
trace("wheel up");
var oldmx:Number = mouseX;
var oldmy:Number = mouseY;
currentScale += 0.1;
trace("currentScale: "+currentScale);
solSys.scaleX = currentScale;
solSys.scaleY = currentScale;
}
}
public function loop(e:Event):void
{
for(var i:uint=0; i < trailPlanets.length; i++)
{
trailPlanets[i].orbit();
trailPlanets[i].updateShadow();
//check if this is the first frame, to prevent drawing a line from each planet's coordinates
//before they are set to an orbit position
if(firstFrame)
{
oldPoints[i].x = trailPlanets[i].x;
oldPoints[i].y = trailPlanets[i].y;
if(i == trailPlanets.length - 1)
{
firstFrame = false;
}
}
//if this planet has trails enabled, draw the latest line
// from the previous line's position to the planet's current position
if(trailPlanets[i].showTrails)
{
trails.graphics.lineStyle(0, trailPlanets[i].trailColour);
trails.graphics.moveTo(oldPoints[i].x, oldPoints[i].y);
trails.graphics.lineTo(trailPlanets[i].x, trailPlanets[i].y);
oldPoints[i].x = trailPlanets[i].x;
oldPoints[i].y = trailPlanets[i].y;
}
earth.updateShadow();
}
}
}
}
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.geom.Point;
class Planet extends Sprite
{
public var radius:uint;
private var fokus:Planet;
public var angularSpeedRad:Number;
private var angleRad:Number = 0;
private var sun:Planet;
private var nabel:String;
private var tf:TextFormat;
private var t:TextField;
private var shadow:Shape = new Shape();
public var showTrails:Boolean = false;
public var trailColour:uint = 0xffffff;
private var orbitCount:uint = 0;
public var period:uint;
private var orbitPoints:Array;
private var i:uint = 0;
private var fokusMoving:Boolean;
//private var totalFrames:uint;
//empty constructor
public function Planet():void
{}
//a simplified lightsource set, for use in the GeoCentric simulation
public function setLightSource(soun:Planet)
{
sun = soun;
}
//draw the "planet", currently only a circle with a solid fill
public function drawPlanet(colour:uint, radius:uint=30, lineColour:uint=0):void
{
graphics.clear();
graphics.lineStyle(0, lineColour);
graphics.beginFill(colour);
graphics.drawCircle(0, 0, radius);
}
//set planet's orbital focus, lightsource, distance from focus,
// and time in frames it takes to complete an orbit
public function setOrbit
(fokus:Planet, sun:Planet, radius:uint = 0, period:uint = 0):void
{
//default data for uint data type is 0
this.fokus = fokus;
this.sun = sun;
this.period = period;
if(fokus.period != 0)
{
fokusMoving = true;
}
else
{
orbitPoints = new Array(period);
fokusMoving = false;
}
if(radius != 0)
{this.radius = radius;}
//trace("period: "+period);
angularSpeedRad = 2*Math.PI/period;
//trace("angularSpeedRad on set: "+angularSpeedRad);
//trace(this);
//trace(nabel+(angularSpeedRad*period) / (2*Math.PI) );
}
//give the planet a name
public function setLabel(nabel:String, textColour:uint=0xffffff, size:uint = 20):void
{
this.nabel = nabel;
tf = new TextFormat("Arial", size, textColour);
t = new TextField();
t.defaultTextFormat = tf;
t.selectable = false;
t.autoSize = "left";
t.text = nabel;
t.textColor = textColour;
addChild(t);
}
//draw initial shadow gradient over each planet
public function drawShadow():void
{
//graphics.clear();
var colours:Array = new Array(0xffffff, 0x000000);
var alphas:Array = new Array(0, 0.9);
var ratios:Array = new Array(0, 140);
shadow.graphics.beginGradientFill("linear", colours, alphas, ratios);
shadow.graphics.drawCircle(0,0, this.width/2);
shadow.graphics.endFill();
addChild(shadow);
}
public function orbit()
{
//are we the centrepiece (earth or sun)?
if(fokus != null)
{
//no
//are we orbiting the centrepiece?
if(!fokusMoving)
{
//yes
//have we completed 1 orbit yet?
if(orbitCount <= period)
{
//no
x = fokus.x + Math.sin(angleRad) * radius;
y = fokus.y + Math.cos(angleRad) * radius;
orbitPoints[orbitCount] = new Point(x,y);
angleRad += angularSpeedRad;// * Math.PI /180;
orbitCount++;
}
else
{
if(i < period)
{
//yes
showTrails = false;
x = orbitPoints[i].x;
y = orbitPoints[i].y;
i++;
}
else
{i=0;}
}
}
else
{
//no, we aren't orbiting the centrepiece. We're prolly a moon
if(nabel == "The Moon")
{
//trace("the moon is a moon :)");
}
/*--all of the old code here is irrelevant, due to my misunderstanding about
the nature of our solar system. I thought that the moon wasn't in
the same position on each orbit of the earth (thus producing a "hetch-a-sketch" pattern) due to an
inconsistency in my code, or computer rounding error. i tried to make it so that the moon WAS in the same
position on the same day each year on the earth, so that the Moon's trail would be drawn exactly over
the last one. I set up an array of points to only calculate the
moon's position once for each day of the earth's year (which I even got wrong, calculating that the number
of unique positions the moon occupies in an earth year to be
the moon's period (28) times the earth's period (earthPeriod). the answer should just have been earthPeriod.
the reason that the moon does not -- in this diagram, nor in real life --
occupy the same position on the same day in each earth year, is that the moon's period (28) does not divide
exactly into THE EARTH'S PERIOD: earthPeriod!
thus there will always be a slight difference in its position each year!*/
//if we're a moon (orbiting a moving planet), our orbit isn't guaranteed to ever repeat,
//so don't try repeating the pattern or trail.
x = fokus.x + Math.sin(angleRad) * radius;
y = fokus.y + Math.cos(angleRad) * radius;
angleRad += angularSpeedRad;// * Math.PI /180;
}
}
}
//update the rotation of the shadow sprite, to make it face the light source
public function updateShadow()
{
var dx:Number = sun.x - x;
var dy:Number = sun.y - y;
var rads = Math.atan2(dy, dx);
rads += Math.PI;
shadow.rotation = rads * 180 / Math.PI;
}
}
/*
///// WONDERFL TRACE /////
import flash.display.Sprite;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
function inittrace(s:Stage):void
{
WTrace.initTrace(s);
}
//global trace function
var trace:Function;
//wtreace class
class WTrace
{
private static var FONT:String = "Fixedsys";
private static var SIZE:Number = 12;
private static var TextFields:Array = [];
private static var trace_stage:Stage;
public static function initTrace(stg:Stage):void
{
trace_stage = stg;
trace = wtrace;
}
private static function scrollup():void
{
// maximum number of lines: 100
if (TextFields.length > 100)
{
var removeme:TextField = TextFields.shift();
trace_stage.removeChild(removeme);
removeme = null;
}
for(var x:Number=0;x<TextFields.length;x++)
{
(TextFields[x] as TextField).y -= SIZE*1.2;
}
}
public static function wtrace(... args):void
{
var s:String="";
var tracefield:TextField;
for (var i:int;i < args.length;i++)
{
// imitating flash:
// putting a space between the parameters
if (i != 0) s+=" ";
s+=args[i].toString();
}
tracefield= new TextField();
tracefield.autoSize = "left";
tracefield.text = s;
tracefield.y = trace_stage.stageHeight - 20;
var tf:TextFormat = new TextFormat(FONT, SIZE);
tracefield.setTextFormat(tf);
trace_stage.addChild(tracefield);
scrollup();
TextFields.push(tracefield);
}
}*/