96 lines
3.1 KiB
Lua
96 lines
3.1 KiB
Lua
local Palette = require("rendering.palette")
|
|
|
|
local Particles = {}
|
|
|
|
local particles = {}
|
|
|
|
function Particles.spawnThrust(x, y, angle)
|
|
-- Jet direction is local (0, 1) rotated by jetAngle (same convention as lander transformPoint)
|
|
local spread = 0.5
|
|
local speed = 30 + math.random() * 40
|
|
local jetAngle = angle + (math.random() - 0.5) * spread
|
|
table.insert(particles, {
|
|
x = x, y = y,
|
|
vx = -math.sin(jetAngle) * speed,
|
|
vy = math.cos(jetAngle) * speed,
|
|
life = 0.2 + math.random() * 0.2,
|
|
maxLife = 0.4,
|
|
ptype = "dot",
|
|
})
|
|
end
|
|
|
|
function Particles.spawnCrash(x, y, vx, vy)
|
|
for i = 1, 20 do
|
|
local angle = math.random() * math.pi * 2
|
|
local speed = 40 + math.random() * 100
|
|
table.insert(particles, {
|
|
x = x, y = y,
|
|
vx = vx * 0.2 + math.cos(angle) * speed,
|
|
vy = vy * 0.2 + math.sin(angle) * speed,
|
|
life = 0.5 + math.random() * 1.0,
|
|
maxLife = 1.5,
|
|
ptype = "dot",
|
|
})
|
|
end
|
|
-- Line debris
|
|
for i = 1, 6 do
|
|
local angle = math.random() * math.pi * 2
|
|
local speed = 30 + math.random() * 60
|
|
local len = 5 + math.random() * 10
|
|
local da = math.random() * math.pi * 2
|
|
table.insert(particles, {
|
|
x = x + (math.random()-0.5)*10, y = y + (math.random()-0.5)*10,
|
|
vx = math.cos(angle) * speed,
|
|
vy = math.sin(angle) * speed - 20,
|
|
lx1 = math.cos(da) * len, ly1 = math.sin(da) * len,
|
|
lx2 = -math.cos(da) * len, ly2 = -math.sin(da) * len,
|
|
rot = 0, rotSpeed = (math.random()-0.5) * 5,
|
|
life = 1.0 + math.random() * 1.0,
|
|
maxLife = 2.0,
|
|
ptype = "line",
|
|
})
|
|
end
|
|
end
|
|
|
|
function Particles.update(dt)
|
|
for i = #particles, 1, -1 do
|
|
local p = particles[i]
|
|
p.x = p.x + p.vx * dt
|
|
p.y = p.y + p.vy * dt
|
|
p.vy = p.vy + 15 * dt -- light gravity on debris
|
|
p.life = p.life - dt
|
|
if p.rot then p.rot = p.rot + (p.rotSpeed or 0) * dt end
|
|
if p.life <= 0 then table.remove(particles, i) end
|
|
end
|
|
end
|
|
|
|
function Particles.clear()
|
|
particles = {}
|
|
end
|
|
|
|
function Particles.anyActive()
|
|
return #particles > 0
|
|
end
|
|
|
|
function Particles.draw()
|
|
local pal = Palette.get()
|
|
for _, p in ipairs(particles) do
|
|
local alpha = math.max(0, p.life / p.maxLife)
|
|
if p.ptype == "dot" then
|
|
love.graphics.setColor(pal.explosion[1], pal.explosion[2], pal.explosion[3], alpha)
|
|
love.graphics.circle("fill", p.x, p.y, 1.5)
|
|
elseif p.ptype == "line" then
|
|
love.graphics.setColor(pal.lander[1], pal.lander[2], pal.lander[3], alpha)
|
|
love.graphics.setLineWidth(1.5)
|
|
local cos_r = math.cos(p.rot)
|
|
local sin_r = math.sin(p.rot)
|
|
local x1 = p.x + p.lx1 * cos_r - p.ly1 * sin_r
|
|
local y1 = p.y + p.lx1 * sin_r + p.ly1 * cos_r
|
|
local x2 = p.x + p.lx2 * cos_r - p.ly2 * sin_r
|
|
local y2 = p.y + p.lx2 * sin_r + p.ly2 * cos_r
|
|
love.graphics.line(x1, y1, x2, y2)
|
|
end
|
|
end
|
|
end
|
|
|
|
return Particles
|