/* Contributed by Kjetil Valstadsve 2008-09-12 */ KEY_LEFT = 37; KEY_RIGHT = 39; KEY_UP = 40; KEY_DOWN = 38; moons = 16; MIN_SIZE = 5 MIN_MASS = 4 * MIN_SIZE * MIN_SIZE SIZE_RANGE = 15; MAX_SIZE = MIN_SIZE + SIZE_RANGE MAX_MASS = 4 * MAX_SIZE * MAX_SIZE - 4 MASS_RANGE = MAX_MASS - MIN_MASS GRAV_LOSS = 0.4 CX = width() / 2 CY = height() / 2 N_GRAV = 0.00001 function collide(radius1, x1, y1, radius2, x2, y2) rad_diff = (radius1 + radius2) / (MIN_SIZE - 1) return ceil(abs(x1 - x2)) < rad_diff and ceil(abs(y1 - y2)) < rad_diff endfunc function pull_from_two_on_one(radius1, mass1, x1, y1, radius2, mass2, x2, y2) adjacent = x2 - x1 opposite = y2 - y1 hypotenuse = sqrt(opposite * opposite + adjacent * adjacent) pulls[0] = hypotenuse if collide(radius1, x1, y1, radius2, x2, y2) then pulls[0] = 0 return pulls endif sinus = opposite / hypotenuse cosinus = adjacent / hypotenuse pull = N_GRAV * mass1 * mass2 / (hypotenuse * hypotenuse); pulls[2] = sinus * pull pulls[1] = cosinus * pull return pulls; endfunc radius[0] = MAX_SIZE * 2 mass[0] = 4 * radius[0] * radius[0] x[0] = CX y[0] = CY dx[0] = 0 dy[0] = 0 pllx[0] = 0.0 plly[0] = 0.0 red[0] = 100 green[0] = 120 blue[0] = 100 for q = 1 to moons do radius[q] = MIN_SIZE + random(SIZE_RANGE) mass[q] = 4 * radius[q] * radius[q] x[q] = random(width() - 1) y[q] = random(height() - 1) dx[q] = 0.0 dy[q] = 0.0 pllx[q] = 0.0; plly[q] = 0.0; red[q] = random(150, 200) green[q] = random(150, 255) blue[q] = random(150, 80) done autoFlush(FALSE) left = 0 while TRUE do t = time() cls() println("Use arrow keys") for p = 0 to moons do if (x[p] - radius[p]) < 0 then x[p] = radius[p] dx[p] = -dx[p] * GRAV_LOSS elseif (x[p] + radius[p]) > width() then x[p] = width() - radius[p] dx[p] = -dx[p] * GRAV_LOSS else x[p] = x[p] + dx[p] endif if (y[p] - radius[p]) < 0 then y[p] = radius[p] dy[p] = -dy[p] * GRAV_LOSS elseif (y[p] + radius[p]) > height() then y[p] = height() - radius[p] dy[p] = -dy[p] * GRAV_LOSS else y[p] = y[p] + dy[p] endif for q = 0 to moons do if p > 0 and p != q then pulls = pull_from_two_on_one (radius[p], mass[p], x[p], y[p], radius[q], mass[q], x[q], y[q]) if pulls[0] == 0 and q != 0 then pllx[p] = 0 plly[p] = 0 else pllx[p] = pulls[1] plly[p] = pulls[2] ertia = 1 // (mass[p] / mass[q]) dx[p] = dx[p] + (pllx[p] * ertia) dy[p] = dy[p] + (plly[p] * ertia) endif endif done done for q = 1 to moons do color(red[q], green[q], blue[q]); rect(x[q] - radius[q], y[q] - radius[q], 2 * radius[q], 2 * radius[q]) done color(red[0], green[0], blue[0]); circle(x[0], y[0], radius[0]) if (keyPressed(KEY_UP)) then y[0] = y[0] - 1 elseif (keyPressed(KEY_DOWN)) then y[0] = y[0] + 1 endif if (keyPressed(KEY_LEFT)) then x[0] = x[0] - 1 elseif (keyPressed(KEY_RIGHT)) then x[0] = x[0] + 1 endif flush() wait(20 - (time() - t)) done