diff --git a/src/main.moon b/src/main.moon new file mode 100644 index 0000000..84b644b --- /dev/null +++ b/src/main.moon @@ -0,0 +1,106 @@ +w, h = love.graphics.getDimensions! +local bodies +time, rate = 0, 1/60 +scale = 1 +G = 100000 + +dist2 = (a, b) -> + dx = a.x - b.x + dy = a.y - b.y + return dx * dx + dy * dy + +gravity = (a, b) -> + dx = a.x - b.x + dy = a.y - b.y + d2 = dx * dx + dy * dy + theta = math.atan2 dy, dx + x = math.cos theta + y = math.sin theta + r2 = (a.r + b.r)^2 + if d2 > r2 + g = G / d2 + a.vx -= b.r * g * x * rate + a.vy -= b.r * g * y * rate + b.vx += a.r * g * x * rate + b.vy += a.r * g * y * rate + else + nil -- FAIL OR WIN CONDITION POSSIBLE HERE + -- red on blue collision = win + -- red on anything else collision = fail + + -- b orbits a + -- doesn't work, have no idea why +setOrbit = (a, b) -> + dx = a.x - b.x + dy = a.y - b.y + d2 = dx * dx + dy * dy + theta = math.atan2 dy, dx + x = math.cos theta + math.pi / 2 + y = math.sin theta + math.pi / 2 + g = G / d2 + b.vx = a.r * g * x + b.vy = a.r * g * y + +class Body + new: (x, y, radius) => + r = love.math.random! * math.pi * 2 + d = love.math.random((w + h)/4) + @x = x or d * math.cos r + @y = y or d * math.sin r + @r = radius or love.math.randomNormal 3, 7 + @vx = 0 + @vy = 0 + @color = { + math.min(1, 1/3 + love.math.random!), + math.min(1, 1/3 + love.math.random!), + math.min(1, 1/3 + love.math.random!), + 1 + } + +love.load = -> + bodies = {} + bodies[1] = Body 0, 0, 20 + for i = 1, love.math.random 3, 7 + -- for i = 1, 1 -- for testing setOrbit in isolation + fail = true + local b + while fail + b = Body! + fail = false + for a = 1, #bodies + if (bodies[a].r + b.r)^2 > dist2 bodies[a], b + fail = true + table.insert bodies, b + bodies[2].color = { 1, 0, 0, 1 } + bodies[1].color = { 0, 0, 1, 1 } + for i = 2, #bodies + setOrbit bodies[1], bodies[i] + +love.update = (dt) -> + time += dt + if time >= rate + time -= rate + + for a = 1, #bodies - 1 + for b = a + 1, #bodies + gravity bodies[a], bodies[b] + + for body in *bodies + body.x += body.vx * rate + body.y += body.vy * rate + +love.draw = -> + love.graphics.translate w / 2, h / 2 + love.graphics.scale scale, scale + for body in *bodies + love.graphics.setColor body.color + love.graphics.circle "fill", body.x, body.y, math.max 1 / scale, body.r + +love.wheelmoved = (x, y) -> + if y > 0 + scale *= 2 + elseif y < 0 + scale /= 2 + +love.keypressed = (key) -> + love.event.quit! if key == "escape"