Ok, just for sh*ts and giggles, here is my (unfinished) solar system simulator.
I was working on this a while ago so I dont know quite to what stage of development it got to before a scaling problem ground it to a complete halt.
I do urge you to check out Guruchild's solar system post in the 'program announcements' forum - its superb. Feel free to rip this one apart for 'spares' as it were - you might find a useful snippet or two.
Controls (I'm only looking in the subroutine so i dont remember quite what happens
)
(some can be used with ctrl/shift for fine/coarse movements)
Return = set zoom to 0
z = toggle labels
space = cycle view (dont know what this does)
left/right = zoom
+/- = manipulate time
numbers 1-9 - view from major bodies
shift + 1-9 - view toward major bodies
Rem Project: solar
Rem Created: 26/07/2003 18:23:25
Rem ***** Main Source File *****
Rem SET UP PROGRAM
restore
cls
set display mode 1024,768,32
set camera range 1,999999
color backdrop rgb(0,0,20)
set text size 14
set text font "Arial"
autocam off
sync off
sync rate 30
`***** LIGHTING EFFECTS *****
`Turn off ambient scene light
set ambient light 75
position light 0,0,0,0
`hide light 0
`Create light source in centre - Ie, the Sun
`make light 1
position light 0,0,0,0
`set point light 1,0,0,0
`color light 1,255,255,255
`set light range 1,200000
`Number of updates per loop, equal to the number of objects
`needing position updates (excluding the sun)
Bodies=77
`Default "speed" of time in our world
TimeFactor#=0
`Optional Variable Names for Easier Referral
Sun = 1
Camera = 200 : `not a real/created object, just storage for positional data
`CREATE ARRAY DIMENSIONS
dim planet#(200,9)
dim BodyName$(200)
dim BodyX#(200)
dim BodyY#(200)
dim BodyZ#(200)
`Bring in Data for astral bodies
for body=1 to Bodies
read value$
BodyName$(body)=value$
for data=2 to 9
read value#
planet#(body,data)=value#
next data
next body
`Bring in camera positional data
read Bodyname$(Camera)
read planet#(Camera,2)
read planet#(Camera,3)
read planet#(Camera,4)
read planet#(Camera,5)
read planet#(Camera,6)
read planet#(Camera,7)
read planet#(Camera,8)
read planet#(Camera,9)
`variables for object properties - remember name is 1
number =2
rank =3
anchor =4
Radius =5
dist =6
orbit =7
Incline =8
Eccentric=9
`MASTER VARIABLES THAT CONTROL THE ENTIRE UNIVERSE
`Divisor to make sizes/distances etc more manageable
master#=100 : `overall controller of scale in the universe, 1 is real but doesnt make for a good simulation
sizemultiplier#=1 : `1 or 2 is real sizes, larger number is larger items
distancemultiplier#=1 : `1 is real distances between bodies, but doesnt look good. 100 looks good.
`Use those variables to modify the object data
for body=1 to bodies
planet#(body,radius)=(planet#(body,radius)/master#)*sizemultiplier#
planet#(body,dist)=(planet#(body,dist)/master#)*distancemultiplier#
planet#(body,eccentric)=planet#(body,eccentric)+1
next body
rem create objects in world
make object sphere sun,planet#(sun,Radius)
position object sun,0,0,0
color object sun,rgb(255,255,0)
make object cube camera,planet#(camera,radius)
position object camera,0,0,0
`hide object camera
for body=2 to Bodies
PRadius#=planet#(body,Radius)
PDist#=planet#(body,dist)
make object sphere body,PRadius#
position object body,PDist#,0,0
randomize timer()/body
color object body,rgb(rnd(256),rnd(256),rnd(256))
next body
`just for laffs
load image "earth.bmp",1
texture object 4,1
`World Default Variables...
ViewFrom=4
ViewTo=1
gosub changeview
Zoom=10
CamDist#=planet#(camera,Dist)
CamOrbital#=planet#(ViewFrom,Orbit)
`TEST BIT
`--------------------------------------------------------------------
rem MAIN LOOP
do
keydelay=keydelay+1
if scancode()<>oldcode then keydelay=0
if keydelay=>2 then keydelay = 0
if scancode()<>0 and keydelay=0 then gosub KeyCommands
gosub MoveBodies
gosub Cameras
gosub TextDisplay
loop
rem END MAIN PROGGY
`--------------------------------------------------------------------
`Move yer astral body..... shifting heaven AND earth!
MoveBodies:
Time#=Time#+TimeFactor#
for Body=2 to Bodies
gosub BodyMoveCode
next Body
Body=Camera
Gosub BodyMoveCode
return
`-------------------------------------------------
`BODY MOVEMENT CODE
BodyMoveCode:
Rad#=Planet#(Planet#(body,anchor),radius)
Distance#=Planet#(Body,Dist)
Orbital#=planet#(Body,Orbit)
Inclination#=Planet#(Body,Incline)
Eccent#=planet#(body,Eccentric)
OffsetX#=Object position x(Planet#(Body,anchor))
Offsetz#=Object position z(Planet#(Body,anchor))
BodyX#(Body)=cos(time#/Orbital#)*(distance#*Eccent#)+offsetX#
BodyZ#(Body)=sin(time#/Orbital#)*(distance#)+offsetZ#
Position object Body,BodyX#(Body),BodyY#(Body),BodyZ#(Body)
Return
`CAMERAS
Cameras:
CamX#=BodyX#(Camera)
CamZ#=BodyZ#(Camera)
position object camera,CamX#,0,CamZ#
SELECT ViewType
CASE 1
position camera object position x(camera),object position y(camera), object position z(camera)
point camera object position x(ViewTo),object position y(ViewTo),object position z(ViewTo)
ENDCASE
CASE 2
POSITION CAMERA object position x(viewfrom),object position y(viewfrom)+zoom,object position z(viewfrom)
point camera object position x(ViewTo),object position y(ViewTo),object position z(ViewTo)
ENDCASE
ENDSELECT
return
`--------------------------------------------------------
`ACCEPT KEYBOARD COMMANDS AND INTEPRET USER REQUIREMENTS
KeyCommands:
OldCode=Scancode()
if escapekey()=1 then end
if returnkey()=1 then zoom=0
if spacekey()=1 then gosub changeview
if inkey$()="z" then label=label+1
if label=>5 then label=0
if controlkey()=1
if rightkey()=1 then Zoom=Zoom-100000
if leftkey()=1 then Zoom=Zoom+100000
if scancode()=12 then timefactor#=timefactor#-1000
if scancode()=13 then timefactor#=timefactor#+1000
endif
if shiftkey()=0
OldViewFrom=ViewFrom
if scancode()=2 then ViewFrom=2
if scancode()=3 then ViewFrom=3
if scancode()=4 then ViewFrom=4
if scancode()=5 then ViewFrom=6
if scancode()=6 then ViewFrom=9
if scancode()=7 then ViewFrom=26
if scancode()=8 then ViewFrom=45
if scancode()=9 then ViewFrom=67
if scancode()=10 then ViewFrom=76
if scancode()=11 then ViewFrom=1
if scancode()=12 then timefactor#=timefactor#-100
if scancode()=13 then timefactor#=timefactor#+100
if rightkey()=1 then Zoom=Zoom-100
if leftkey()=1 then Zoom=Zoom+100
if upkey()=1 then ViewFrom=ViewFrom+1
if downkey()=1 then viewfrom=viewfrom-1
endif
if shiftkey()=1
if scancode()=2 then ViewTo=2
if scancode()=3 then ViewTo=3
if scancode()=4 then ViewTo=4
if scancode()=5 then ViewTo=6
if scancode()=6 then ViewTo=9
if scancode()=7 then ViewTo=26
if scancode()=8 then ViewTo=45
if scancode()=9 then ViewTo=67
if scancode()=10 then ViewTo=76
if scancode()=11 then ViewTo=1
if scancode()=12 then timefactor#=timefactor#-1
if scancode()=13 then timefactor#=timefactor#+1
if rightkey()=1 then planet#(Camera,Dist)=Planet#(camera,dist)+(100000/master#)
if leftkey()=1 then planet#(Camera,Dist)=Planet#(camera,dist)-(100000/master#)
if upkey()=1 then ViewTo=ViewTo+1
if downkey()=1 then viewTo=viewTo-1
endif
if viewfrom<>oldviewfrom
Planet#(Camera,anchor) =Planet#(Viewfrom,anchor)
Planet#(Camera,Dist) =Planet#(Viewfrom,Dist)
Planet#(Camera,Eccentric)=Planet#(ViewFrom,Eccentric)
Planet#(Camera,Orbit) =Planet#(Viewfrom,Orbit)
Planet#(Camera,Incline) =Planet#(ViewFrom,Incline)
endif
if zoom<0 then zoom=0
if viewfrom>bodies then viewfrom=1
if viewfrom<1 then viewfrom=bodies
if viewto>bodies then viewto=1
if viewto<1 then viewto=bodies
return
`SWITCH CAMERA MODE
ChangeView:
viewtype=viewtype+1
if viewtype=3 then viewtype=1
SELECT viewtype
CASE 1
View$=""
Zoom=0
ENDcase
Case 2
View$="Above"
Zoom=Planet#(ViewTo,Radius)
endcase
ENDSELECT
return
`ON SCREEN TEXT DISPLAYS
TextDisplay:
center text 512,50,"Viewing From: "+View$+" "+bodyname$(ViewFrom)+" to "+bodyname$(ViewTo)
center text 512,65,"Zoom: "+str$(Zoom)
text 900,10,"FPS: "+str$(Screen FPS())
text 10,10,"Time Actual: "+str$(Time#)
text 300,10," ("+str$(int(time#/365.26))+" Days)"
text 10,20,"Time Factor: "+str$(timefactor#)
text 10,40,"VIEW FROM INFO:"
text 10,55,"Name: "+bodyname$(ViewFrom)
text 10,65,"Size(Km): "+str$(planet#(viewfrom,Radius))
text 10,75,"In orbit of: "+bodyname$(int(planet#(viewfrom,anchor)))
text 10,85,"Orbit Dist: "+str$(planet#(ViewFrom,dist))
text 10,95,"Year(Days): "+str$(int(planet#(ViewFrom,orbit)))
text 10,125,"Cam Orbits: "+bodyname$(int(planet#(camera,anchor)))
text 10,135,"Cam Orb Dist: "+str$(planet#(camera,dist))
text 10,145,"Cam Orb Days: "+str$(planet#(camera,orbit))
for A=1 to Bodies
if label>=planet#(a,rank)
XPos=Object Screen x(a)
YPos=Object Screen y(a)
If XPos>950 then Xpos=950
if Xpos<5 then Xpos=5
If YPos>755 then Ypos=755
If Ypos<5 then YPos=5
Text Xpos,Ypos,bodyname$(a)
endif
next A
`remstart
XPos=Object Screen x(Camera)
YPos=Object Screen y(Camera)
If XPos>950 then Xpos=950
if Xpos<5 then Xpos=5
If YPos>755 then Ypos=755
If Ypos<5 then YPos=5
Text Xpos,Ypos,bodyname$(Camera)
`remend
if label=0 then label$="NONE!"
if label=1 then label$="Stars"
if label=2 then label$="Stars, Planets"
if label=3 then label$="Stars, Planets, Moons"
if label=4 then label$="Stars, Planets, Moons, Satellites"
text 10,750,"Labels: "+label$
return
rem 1. Object No (Referrered to in the code)
rem 2. Object Name (String)
rem 3, Object Rank (1=Star, 2=Planet, 3=Moon, 4=Minor Satellite)
rem 4. Anchor (The object which this object orbits around)
rem 5. Radius (Object Radius in Km)
rem 6. Anchor Dist (Distance this object orbits away from its anchor)
rem 7. Orbital Period (Number of [earth] days this object takes to do one full orbit)
rem 8. Inclination (Angle at which this object orbits)
rem 9. Eccentricity (Factor to determine shape of eliptical orbit 0=perfect circle)
rem 1 2 3 4 5 6 7 8 9
rem --------------------------------------------------------------------
data "SOL" ,1 ,1,1 ,695000 ,0 ,0 ,0 ,0
data "MERCURY" ,2 ,2,1 ,2440 ,57910000 ,87.97 ,7.00 ,0.21
data "VENUS" ,3 ,2,1 ,6052 ,108200000 ,224.7 ,3.39 ,0.01
data "EARTH" ,4 ,2,1 ,6378 ,149600000 ,365.26 ,0.00 ,0.02
data "Moon" ,5 ,3,4 ,1738 ,384000 ,27.32 ,5.14 ,0.05
data "MARS" ,6 ,2,1 ,3397 ,227940000 ,686.98 ,1.85 ,0.09
data "Phobos" ,7 ,3,6 ,11 ,9000 ,0.32 ,1.00 ,0.02
data "Deimos" ,8 ,3,6 ,6 ,23000 ,1.26 ,1.80 ,0.00
data "JUPITER" ,9 ,2,1 ,71492 ,778330000 ,4332.71 ,1.31 ,0.05
data "Metis" ,10 ,3,9 ,20 ,128000 ,0.29 ,0.00 ,0.00
data "Adrastea" ,11 ,3,9 ,10 ,129000 ,0.30 ,0.00 ,0.00
data "Amalthea" ,12 ,3,9 ,94 ,181000 ,0.50 ,0.40 ,0.00
data "Thebe" ,13 ,3,9 ,50 ,222000 ,0.67 ,0.80 ,0.02
data "Io" ,14 ,3,9 ,1821 ,422000 ,1.77 ,0.04 ,0.00
data "Europa" ,15 ,3,9 ,1565 ,671000 ,3.55 ,0.47 ,0.01
data "Ganymede" ,16 ,3,9 ,2634 ,1070000 ,7.15 ,0.19 ,0.00
data "Callisto" ,17 ,3,9 ,2403 ,1883000 ,16.69 ,0.28 ,0.01
`data "Themisto" , ,3,9 ,
data "Leda" ,18 ,3,9 ,8 ,11094000 ,238.72 ,27 ,0.15
data "Himalia" ,19 ,3,9 ,93 ,11480000 ,250.57 ,28 ,0.16
data "Lysithea" ,20 ,3,9 ,18 ,11720000 ,259.22 ,29 ,0.11
data "Elara" ,21 ,3,9 ,38 ,11737000 ,259.65 ,28 ,0.21
data "Ananke" ,22 ,3,9 ,15 ,21200000 ,-631 ,147 ,0.17
data "Carme" ,23 ,3,9 ,20 ,22600000 ,-692 ,163 ,0.21
data "Pasiphae" ,24 ,3,9 ,25 ,23500000 ,-735 ,147 ,0.38
data "Sinope" ,25 ,3,9 ,18 ,23700000 ,-758 ,153 ,0.28
`data "Iocaste" , ,3,9 ,
`data "Harpalyke" , ,3,9 ,
`data "Praxidike" , ,3,9 ,
`data "Taygete" , ,3,9 ,
`data "Chaldene" , ,3,9 ,
`data "Kalyke" , ,3,9 ,
`data "Callirrhoe", ,3,9 ,
`data "Megaclite" , ,3,9 ,
`data "Isonoe" , ,3,9 ,
`data "Erinome" , ,3,9 ,
data "SATURN" ,26 ,2,1 ,60268 ,1429400000 ,10759.50,2.49 ,0.06
data "Pan" ,27 ,3,26,10 ,134000 ,.58 ,0 ,0
data "Atlas" ,28 ,3,26,15 ,138000 ,.60 ,0 ,0
data "Prometheus",29 ,3,26,46 ,139000 ,.61 ,0 ,0
data "Pandora" ,30 ,3,26,42 ,142000 ,.63 ,0 ,0
data "Epimetheus",31 ,3,26,57 ,151000 ,.69 ,.34 ,.01
data "Janus" ,32 ,3,26,89 ,151000 ,.69 ,.14 ,.01
data "Mimas" ,33 ,3,26,199 ,186000 ,.94 ,1.53 ,.02
data "Enceladus" ,34 ,3,26,249 ,238000 ,1.37 ,.02 ,0
data "Tethys" ,35 ,3,26,530 ,295000 ,1.89 ,1.09 ,0
data "Telesto" ,36 ,3,26,15 ,295000 ,1.89 ,0 ,0
data "Calypso" ,37 ,3,26,13 ,295000 ,1.89 ,0 ,0
data "Dione" ,38 ,3,26,560 ,377000 ,2.74 ,.02 ,0
data "Helene" ,39 ,3,26,16 ,377000 ,2.74 ,.2 ,.01
data "Rhea" ,40 ,3,26,764 ,527000 ,4.52 ,.35 ,0
data "Titan" ,41 ,3,26,2575 ,1222000 ,15.95 ,.33 ,.03
data "Hyperion" ,42 ,3,26,143 ,1481000 ,21.28 ,.43 ,.1
data "Iapetus" ,43 ,3,26,718 ,3561000 ,79.33 ,14.72 ,0.03
data "Phoebe" ,44 ,3,26,110 ,12952000 ,-550.48 ,175.3 ,.16
data "URANUS" ,45 ,2,1 ,25559 ,2870990000 ,30685 ,.77 ,.05
data "Cordelia" ,46 ,3,45,13 ,50000 ,.34 ,.14 ,0
data "Ophelia" ,47 ,3,45,16 ,54000 ,.38 ,.09 ,0
data "Bianca" ,48 ,3,45,22 ,59000 ,.43 ,.16 ,0
data "Cressida" ,49 ,3,45,33 ,62000 ,.46 ,.04 ,0
data "Desdemona" ,50 ,3,45,29 ,63000 ,.47 ,.16 ,0
data "Juliet" ,51 ,3,45,42 ,64000 ,.49 ,.06 ,0
data "Portia" ,52 ,3,45,55 ,66000 ,.51 ,.09 ,0
data "Rosalind" ,53 ,3,45,27 ,70000 ,.56 ,.28 ,0
data "Belinda" ,54 ,3,45,34 ,75000 ,.62 ,.03 ,0
data "1986U10" ,55 ,3,45,20 ,76000 ,.64 ,0 ,0
data "Puck" ,56 ,3,45,77 ,86000 ,.76 ,.31 ,0
data "Miranda" ,57 ,3,45,236 ,130000 ,1.41 ,4.22 ,0
data "Ariel" ,58 ,3,45,581 ,191000 ,2.52 ,0 ,0
data "Umbriel" ,59 ,3,45,585 ,266000 ,4.14 ,0 ,0
data "Titania" ,60 ,3,45,789 ,436000 ,8.71 ,0 ,0
data "Oberon" ,61 ,3,45,761 ,583000 ,13.46 ,0 ,0
data "Caliban" ,62 ,3,45,40 ,7169000 ,-580 ,140 ,.08
data "Stephano" ,63 ,3,45,15 ,7948000 ,-674 ,143 ,.24
data "Sycorax" ,64 ,3,45,80 ,12213000 ,-1289 ,153 ,.51
data "Prospero" ,65 ,3,45,20 ,16568000 ,-2019 ,152 ,.44
data "Setebos" ,66 ,3,45,20 ,17681000 ,-2239 ,158 ,.57
data "NEPTUNE" ,67 ,2,1 ,24766 ,4504300000 ,60190 ,1.77 ,.01
data "Naiad" ,68 ,3,67,29 ,48000 ,.29 ,0 ,0
data "Thalassa" ,69 ,3,67,40 ,50000 ,.31 ,4.5 ,0
data "Despina" ,70 ,3,67,74 ,53000 ,.33 ,0 ,0
data "Galatea" ,71 ,3,67,79 ,62000 ,.43 ,0 ,0
data "Larissa" ,72 ,3,67,96 ,74000 ,.55 ,0 ,0
data "Proteus" ,73 ,3,67,209 ,118000 ,1.12 ,0 ,0
data "Triton" ,74 ,3,67,1353 ,355000 ,-5.88 ,157 ,0
data "Nereid" ,75 ,3,67,170 ,5513000 ,360.13 ,29 ,.75
data "PLUTO" ,76 ,2,1 ,1150 ,5913520000 ,90550 ,17.15 ,.25
data "Charon" ,77 ,3,76,586 ,20000 ,6.39 ,98.8 ,0
data "CAMERA" ,200,5,1 ,10 ,149600000 ,365.26 ,0 ,0.02
God of unfinished programming projects