Random planets
Scroll and drag to zoom/pan. (No mobile support.)
This was inspired by the JS13K 2018 submission "Exo" by Jack Oatley and Anton K. I wanted to make a strategy game focused around building structures in orbits of limited space that can also be taken up by moons / planets.
This particular sketch was an experiment in making a simple logical structure which assigns whole numbers to planet masses and orbit "sizes", but at the same time disallows overlapping orbits.
I ended up with a system structured around the fibonacci numbers: a size-n planet has mass equal to F_n, the n-th fibonacci number, takes up F_{n+1} spaces on an orbit, and has n/2-2 orbits with available space ranging from F_{n/2+1} to F_{n-1}.
The big numbers displayed are "gravity potentials", to be used for computing the energy needed to travel from surface/orbit to surface/orbit.
function setup() {
createCanvas(windowWidth, windowHeight);
pan = createVector(0, 0)
time = (random() + random() + 1) * 100000000
}
let zoom = 0
let pan
let time = 1441432
function draw() {
background(220)
randomSeed(100)
textAlign(CENTER, CENTER)
if (mouseIsPressed) {
pan.x += mouseX - pmouseX
pan.y += mouseY - pmouseY
}
translate(pan)
scale(2 ** (zoom/12))
strokeWeight(2 ** (-zoom/12))
drawFull(width/2, height/2, 16, 0)
time += deltaTime / 1000 * (keyIsDown(32)?125:25) * (2 ** (-zoom/12))
resetMatrix()
strokeWeight(1)
fill(0)
noStroke()
{
textAlign(RIGHT, BOTTOM)
textSize(10)
let d = time / 60
let m = d / 30; d %= 30
let y = m / 12; m %= 12
let c = y / 1000; y %= 1000
text(`epoch ${floor(c)}, ${('00' + floor(y)).slice(-3)}-${('0' + floor(m+1)).slice(-2)}-${('0' + floor(d+1)).slice(-2)}`, width, height)
}
}
function mouseWheel(event) {
let oldzoom = zoom
if (event.delta > 0) {
zoom--
} else {
zoom++
}
pan.x = (pan.x - mouseX) * (2 ** ((zoom-oldzoom)/12)) + mouseX
pan.y = (pan.y - mouseY) * (2 ** ((zoom-oldzoom)/12)) + mouseY
}
let fibs = [1, 1]
{
while (fibs.length < 30) {
fibs[fibs.length] = fibs[fibs.length-1] + fibs[fibs.length-2]
}
}
function drawFull(x, y, size, evt) {
let mass = fibs[size]
fill(255)
stroke(0)
circle(x, y, (mass ** (1/2)) * 4)
for (let i = floor(size/2)+1; i <= size - 2; i++) {
drawOrbit(x, y, i, i-2, evt + (mass / fibs[i]) ** 0.5)
}
fill(0)
noStroke()
textSize(sqrt(fibs[size] + 10) * 4 * 1.2 ** (-zoom/12))
let ev = mass ** (1/2-1/6)
text(round((evt + ev) * 4), x, y)
}
function drawOrbit(x, y, distance, size, evt) {
let r = fibs[distance] * 5
let period = (fibs[distance] / fibs[12]) ** 1.5 * 14400
let t = ((time / period)%1 + random())*PI*2 * (random()<0.01?-1:1)
let sections = fibs[distance+1]
noFill()
stroke(0)
let dashes = sections / 1
for (let i = 0; i < dashes; i ++) {
arc(x, y, r * 2, r * 2, (i-0.25)/dashes*2*PI+t, (i+0.25)/dashes*2*PI+t, OPEN)
}
let z = 0
let a = 0
while (a < sections) {
let sub = floor(random(size)) + 1
let inc = fibs[sub+1]
while (sub > 1 && a + inc >= sections) {
sub --
inc = fibs[sub+1]
}
if (random() > 0.1) {
drawFull(x + r * cos((a + inc/2)/sections*PI*2+t), y + r * sin((a + inc/2)/sections*PI*2+t), sub, evt)
}
a += inc
}
fill(0)
noStroke()
textSize(sqrt(evt) * 4 * 1.2 ** (-zoom/12))
text(round(evt*4), x + r, y)
}(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/qk-1cumfp)
Browse more articles?
← Chunked rects Experiments tagged p5 (11/85) Drifting car →
|← Experiments tagged wip (1/5) Circle lockpick →
← Chunked rects Experiments on this site (11/85) Drifting car →