oma-lander/game/particles.lua
2026-04-18 23:20:40 +01:00

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