Solar System Simulator

I'm still waiting for my supper to cook, so I've written a simple solar system simulator.  Create any number of 'planets' and put them into random orbits around a star.  Sure, some of the planets are going to be ejected into deep space, never to been seen again, but for the lucky few - you may see a stable orbit, and who knows, if the conditions are right maybe life will flourish?


Again, keen students will want to change a few parameters.  The solar gravity is a good one to modify, as is the number of planets created.  Have fun, and as always, this program will run under the free version of BB4Win, and Windows executables are available on demand.

Source code follows:

     REM Solar System Simulator
     REM T Street
     REM 2014-11-25
     
MODE 10  : OFF
     
REM screen dimensions
     
SCREEN_WIDTH% = 1440
     SCREEN_HEIGHT% = 1152

     REM -------------------------------------------
     REM STUFF TO MUCK AROUND WITH
     REM -------------------------------------------
     
SUN_RADIUS% = 100 : REM pixels
     
SUN_MASS% = 100   : REM relative units
     
PLANETS% = 30
     REM -------------------------------------------

     
BLACK% = 1 : COLOUR BLACK%, 0, 0, 0
     SUN_COL% = 2 : COLOUR SUN_COL%, 255, 255, 0
     PLANET_COL% =  3 : REM colour pot for planets
     
PLANET_MULT% = 4 : REM size of planet per unit of mass

     REM create the planet structure
     
DIM planet{(PLANETS%-1) x, y, dx, dy, mass, green%, blue% }

     REM randomly create planets
     
PROC_createPlanet( planet{()} )

     REM MAIN LOOP
     
REPEAT
       
*refresh off
       PROC_drawSun
       PROC_drawPlanets( planet{()} )
       *refresh
       WAIT 5
       *refresh off
       PROC_removePlanets( planet{()} )
       *refresh
       PROC_move( planet{()} )
       PROC_gravity( planet{()} )
     UNTIL FALSE



     
DEFPROC_createPlanet( this{()} )
     REM creates random planets
     
LOCAL i%
     FOR i% = 0 TO PLANETS%-1
       this{(i%)}.x  = RND(SCREEN_WIDTH%)
       this{(i%)}.y  = RND(SCREEN_HEIGHT%)
       this{(i%)}.dx = RND(10)+5
       this{(i%)}.dy = RND(10)+5
       this{(i%)}.green% = RND(256)-1
       this{(i%)}.blue% = RND(256)-1
       this{(i%)}.mass = RND(10)
     NEXT
     ENDPROC


     
DEFPROC_drawSun
     REM draws the yellow star in center of screen
     
GCOL 0, SUN_COL%
     CIRCLE FILLSCREEN_WIDTH% DIV 2, SCREEN_HEIGHT% DIV 2, SUN_RADIUS%
     ENDPROC


     
DEFPROC_drawPlanets( this{()} )
     REM draw each planet
     
LOCAL i%
     FOR i% = 0 TO PLANETS% -1
       COLOUR PLANET_COL%, 0, this{(i%)}.green%, this{(i%)}.blue%
       GCOL 0, PLANET_COL%
       CIRCLE FILL this{(i%)}.x, this{(i%)}.y, this{(i%)}.mass * PLANET_MULT%
     NEXT
     ENDPROC

     
DEFPROC_removePlanets( this{()} )
     REM remove planets from the screen
     
LOCAL i%
     GCOL 0, BLACK%
     FOR i% = 0 TO PLANETS% -1
       CIRCLE FILL this{(i%)}.x, this{(i%)}.y, this{(i%)}.mass * PLANET_MULT%
     NEXT
     ENDPROC


     
DEFPROC_move( this{()} )
     REM move planet due to its own velocity
     
LOCAL i%
     FOR i% = 0 TO PLANETS% -1
       this{(i%)}.x += this{(i%)}.dx
       this{(i%)}.y += this{(i%)}.dy
     NEXT
     ENDPROC


     
DEFPROC_gravity( this{()} )
     REM apply gravity to each planet from the sun
     
LOCAL distance
     LOCAL i% : REM iterator
     
FOR i% = 0 TO PLANETS% - 1
       distance = SQR( (SCREEN_WIDTH% DIV 2 - this{(i%)}.x)^2 + (SCREEN_HEIGHT% DIV 2 - this{(i%)}.y)^2 )
       IF distance<>0 THEN
         
this{(i%)}.dx += ( this{(i%)}.mass * SUN_MASS% * (SCREEN_WIDTH% DIV 2 - this{(i%)}.x) / distance^2 )
         this{(i%)}.dy += ( this{(i%)}.mass * SUN_MASS% * (SCREEN_HEIGHT% DIV 2 - this{(i%)}.y) / distance^2 )
       ENDIF
     NEXT
     ENDPROC