281 lines
6.6 KiB
Lua
281 lines
6.6 KiB
Lua
function love.load()
|
|
--options
|
|
love.graphics.setColor(1,1,1)
|
|
love.graphics.setDefaultFilter("nearest") -- good pixel
|
|
|
|
SCREEN_WIDTH = love.graphics.getWidth()
|
|
SCREEN_HEIGHT = love.graphics.getHeight()
|
|
|
|
require "class"
|
|
require "body"
|
|
|
|
-- simulation variables
|
|
CONST_G = 39.5
|
|
CONST_S = 0.15
|
|
|
|
-- time
|
|
T = 0
|
|
DT = 1/60
|
|
TIME_SPEED = 0.25
|
|
CURR_TS = 0
|
|
|
|
-- view
|
|
VIEW = {}
|
|
VIEW.x = 0
|
|
VIEW.y = 0
|
|
VIEW.size = 104
|
|
VIEW.planet_size = 40
|
|
VIEW.prints = {}
|
|
VIEW.print_time = 1/4
|
|
VIEW.orbit_prints = {}
|
|
VIEW.orbit_print_time = 1500
|
|
VIEW.fixated = true
|
|
|
|
newBody(
|
|
{
|
|
pos = {0, 0, 0},
|
|
vel = {-0, 0, 0},
|
|
mass = 40000,
|
|
color = {1,0,0}
|
|
}
|
|
)
|
|
newBody(
|
|
{
|
|
pos = {10000, 0, 0},
|
|
vel = {0, 100000, 0},
|
|
mass = 200,
|
|
color = {0,1,0}
|
|
}
|
|
)
|
|
newBody(
|
|
{
|
|
pos = {20000, 0, 0},
|
|
vel = {0, 100000, 0},
|
|
mass = 400,
|
|
color = {0,0,1}
|
|
}
|
|
)
|
|
newBody(
|
|
{
|
|
pos = {0, 20000, 0},
|
|
vel = {-200000, 0, 0},
|
|
mass = 3000,
|
|
color = {0,1,1}
|
|
}
|
|
)
|
|
newBody(
|
|
{
|
|
pos = {0, -20000, 0},
|
|
vel = {200000, 0, 0},
|
|
mass = 3000,
|
|
color = {0,1,1}
|
|
}
|
|
)
|
|
end
|
|
|
|
function love.keypressed(key)
|
|
if key == "space" then
|
|
if CURR_TS == 0 then
|
|
CURR_TS = TIME_SPEED
|
|
else
|
|
CURR_TS = 0
|
|
end
|
|
end
|
|
if key == "up" or key == "right" then
|
|
CURR_TS = CURR_TS + 0.1
|
|
end
|
|
if key == "down" or key == "left" then
|
|
CURR_TS = CURR_TS - 0.1
|
|
end
|
|
CURR_TS = math.max(0, CURR_TS)
|
|
if key == "z" then
|
|
VIEW.fixated = not VIEW.fixated
|
|
end
|
|
end
|
|
|
|
function love.update(dt)
|
|
T = math.floor((T + DT * CURR_TS)*1000)/1000
|
|
-- merge planets that collision
|
|
for i=1, #BodyList do
|
|
for j=i+1, #BodyList do
|
|
if BodyList[i] and BodyList[j] then
|
|
local body = BodyList[i]
|
|
local other_body = BodyList[j]
|
|
local size = body.size/VIEW.size
|
|
local other_size = VIEW.planet_size*math.sqrt(other_body.mass)
|
|
|
|
if math.sqrt(
|
|
(other_body.x - body.x) * (other_body.x - body.x) +
|
|
(other_body.y - body.y) * (other_body.y - body.y) +
|
|
(other_body.z - body.z) * (other_body.z - body.z)
|
|
) < (size + other_size) * 2
|
|
then
|
|
print("matching ".. i .. " and " .. j)
|
|
print("original "..i.." pos {"..body.x..", "..body.y..", "..body.z.."}")
|
|
print("original "..i.." vel {"..body.vx..", "..body.vy..", "..body.vz.."}")
|
|
|
|
print("original "..j.." pos {"..other_body.x..", "..other_body.y..", "..other_body.z.."}")
|
|
print("original "..j.." vel {"..other_body.vx..", "..other_body.vy..", "..other_body.vz.."}")
|
|
|
|
local new_x = (body.x + other_body.x) / 2
|
|
local new_y = (body.y + other_body.y) / 2
|
|
local new_z = (body.z + other_body.z) / 2
|
|
print("new pos {"..new_x..", "..new_y..", "..new_z.."}")
|
|
|
|
local new_vx = (body.vx + other_body.vx) / 2
|
|
local new_vy = (body.vy + other_body.vy) / 2
|
|
local new_vz = (body.vz + other_body.vz) / 2
|
|
print("new vel {"..new_vx..", "..new_vy..", "..new_vz.."}")
|
|
|
|
local new_mass = body.mass + other_body.mass
|
|
print("new mass "..new_mass)
|
|
|
|
local new_color_r = (body.color[1]+other_body.color[1])/2
|
|
local new_color_g = (body.color[2]+other_body.color[2])/2
|
|
local new_color_b = (body.color[3]+other_body.color[3])/2
|
|
print("new color {"..new_color_r..", "..new_color_g..", "..new_color_b.."}")
|
|
|
|
newBody(
|
|
{
|
|
pos = {new_x, new_y, new_z},
|
|
vel = {new_vx, new_vy, new_vz},
|
|
mass = new_mass,
|
|
color = {new_color_r,new_color_g,new_color_b}
|
|
}
|
|
)
|
|
|
|
BodyList[i] = nil
|
|
BodyList[j] = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
UpdateBodiesAcceleration()
|
|
UpdateBodiesVelocity(DT * CURR_TS)
|
|
UpdateBodiesPosition(DT * CURR_TS)
|
|
|
|
-- get previous view offset
|
|
local pvx = VIEW.x
|
|
local pvy = VIEW.y
|
|
-- center camera on bigger one
|
|
local vm = 0
|
|
for n, body in pairs(BodyList) do
|
|
if body.mass > vm then
|
|
vm = body.mass
|
|
VIEW.x = -body.x
|
|
VIEW.y = -body.y
|
|
end
|
|
end
|
|
-- adjust sizes to slowest mass
|
|
local vm = 0
|
|
for n, body in pairs(BodyList) do
|
|
if body.max_distance >= vm then
|
|
vm = body.max_distance
|
|
VIEW.size = math.sqrt(body.max_distance)
|
|
end
|
|
end
|
|
if VIEW.size == 0 and #BodyList > 0 then
|
|
VIEW.fixated = false
|
|
VIEW.size = math.sqrt(BodyList[1].mass)
|
|
end
|
|
-- adjust orbit trails to the reference object
|
|
if VIEW.fixated then
|
|
for n, print in pairs(VIEW.orbit_prints) do
|
|
print.pos.x = print.pos.x - VIEW.x + pvx
|
|
print.pos.y = print.pos.y - VIEW.y + pvy
|
|
end
|
|
end
|
|
-- clean list of bodies
|
|
local bl = {}
|
|
for _, body in pairs(BodyList) do
|
|
if body then
|
|
table.insert(bl, body)
|
|
end
|
|
end
|
|
BodyList = bl
|
|
end
|
|
|
|
function love.draw()
|
|
love.graphics.setColor(1,1,1)
|
|
-- draw bodies
|
|
for n, body in pairs(BodyList) do
|
|
addPrint(body)
|
|
end
|
|
drawObitPrints()
|
|
drawPrints()
|
|
-- draw info
|
|
love.graphics.setColor(1,1,1)
|
|
love.graphics.print("x,y: " .. VIEW.x .. VIEW.y .. " size: " .. VIEW.size .. " T: ".. T)
|
|
for n, body in pairs(BodyList) do
|
|
love.graphics.setColor(body.color[1],body.color[2],body.color[3])
|
|
local TT = ""
|
|
if body.origin then
|
|
TT = "T: " .. body.origin.T
|
|
end
|
|
love.graphics.print("mass: "..body.mass..TT..", x,y: "..body.x..", "..body.y..", vx, vy:"..body.vx..", "..body.vy,0,15*n)
|
|
end
|
|
end
|
|
|
|
function addPrint(body)
|
|
table.insert(VIEW.prints,{
|
|
pos = {
|
|
x = body.x,
|
|
y = body.y
|
|
},
|
|
mass = body.mass,
|
|
color = body.color,
|
|
time = VIEW.print_time
|
|
})
|
|
local trail_color = {
|
|
(1 + body.color[1])/2,
|
|
(1 + body.color[2])/2,
|
|
(1 + body.color[3])/2
|
|
}
|
|
|
|
if CURRENT_TS ~= 0 then
|
|
table.insert(VIEW.orbit_prints,{
|
|
pos = {
|
|
x = body.x,
|
|
y = body.y
|
|
},
|
|
mass = 1,
|
|
color = trail_color,
|
|
time = VIEW.orbit_print_time
|
|
})
|
|
end
|
|
end
|
|
|
|
function drawPrints()
|
|
for n, print in pairs(VIEW.prints) do
|
|
love.graphics.setColor(print.color[1],print.color[2],print.color[3],print.time/VIEW.print_time)
|
|
love.graphics.circle(
|
|
"line",
|
|
(VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2,
|
|
(VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2,
|
|
VIEW.planet_size * math.sqrt(print.mass)/VIEW.size * (print.time/VIEW.print_time)
|
|
)
|
|
print.time = print.time - CURR_TS
|
|
if print.time < 1
|
|
or print.time > VIEW.print_time then
|
|
VIEW.prints[n] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function drawObitPrints()
|
|
for n, print in pairs(VIEW.orbit_prints) do
|
|
love.graphics.setColor(print.color[1],print.color[2],print.color[3],print.time/VIEW.orbit_print_time)
|
|
love.graphics.circle(
|
|
"line",
|
|
(VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2,
|
|
(VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2,
|
|
print.mass/VIEW.size * (print.time/VIEW.orbit_print_time)
|
|
)
|
|
print.time = print.time - CURR_TS
|
|
if print.time < 1
|
|
or print.time > VIEW.orbit_print_time then
|
|
VIEW.orbit_prints[n] = nil
|
|
end
|
|
end
|
|
end |