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