Skip to content

Instantly share code, notes, and snippets.

@gersande
Forked from joshski/flame.lua
Last active May 16, 2023 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gersande/f7f60fbb731820c6b222 to your computer and use it in GitHub Desktop.
Save gersande/f7f60fbb731820c6b222 to your computer and use it in GitHub Desktop.
-- a little flame in a functional style
function particle(step, style, t)
local newStyle = step(style, t)
return {
style = newStyle,
next = function()
return particle(step, newStyle, t + 1)
end
}
end
function flame(particles, t)
local newParticles = evolve(particles, t)
return {
particles = newParticles,
next = function()
return flame(newParticles, t + 1)
end
}
end
function evolve(particles, t)
return generate(mutate(prune(particles)), t)
end
function mutate(particles)
return map(particles, function(p)
return p.next()
end)
end
function prune(particles)
return filter(particles, function(p)
return p.style.a > 0
end)
end
function each(things, fn)
for i, thing in ipairs(things) do
fn(thing)
end
end
function map(things, convert)
local mapped = {}
each(things, function(thing)
table.insert(mapped, convert(thing))
end)
return mapped
end
function cons(things, ...)
local all = {}
each(things, function(t)
table.insert(all, t)
end)
each({...}, function(t)
table.insert(all, t)
end)
return all
end
function filter(things, fn)
local filtered = {}
for i, thing in ipairs(things) do
if fn(thing) then
table.insert(filtered, thing)
end
end
return filtered
end
function spark(style, t)
return {
x = style.x - math.sin(t * 0.436),
y = style.y + 1,
r = style.r + (math.sin(t * style.o) * 40),
g = style.g + (math.sin(t * style.o) * 33),
b = style.b + (math.sin(t * style.o) * 15),
a = (style.a - 4 * style.o) * 0.97,
o = style.o * 0.977,
radius = 5 - t * 0.03
}
end
function generate(particles, t)
return cons(particles,
particle(spark, {
x = -3,
y = 2,
r = 255,
g = 40,
b = 10,
a = 220,
o = 0.5
} , 9),
particle(spark, {
x = 2,
y = 2,
r = 150,
g = 73,
b = 10,
a = 220,
o = 0.5
} , 4),
particle(spark, {
x = -1,
y = 1,
r = 255,
g = 128,
b = 51,
a = 220,
o = math.sin(t) * 0.9
}, t % 10),
particle(spark, {
x = -2,
y = 0,
r = 111,
g = 40,
b = 40,
a = 191,
o = 0.714
} , 9),
particle(spark, {
x = 1,
y = 0,
r = 170,
g = 83,
b = 32,
a = 220,
o = 0.4 + (math.sin(t) * 0.362)
}, t % 3),
particle(spark, {
x = 0.7,
y = 1,
r = 168,
g = 83,
b = 5,
a = 250,
o = 0.4
}, t % 4),
particle(spark, {
x = 1,
y = 0,
r = 177,
g = 72,
b = 17,
a = 219,
o = 1.154
}, 0),
particle(spark, {
x = -0.5,
y = 1,
r = 189,
g = 20,
b = 17,
a = 219,
o = 0.6
}, 3)
)
end
f = flame({}, 0)
function draw()
background(59, 51, 82, 255)
translate(WIDTH/2,HEIGHT/2)
each(f.particles, function(p)
drawParticle(p)
end)
f = f.next()
end
function drawParticle(p)
fill(p.style.r, p.style.g, p.style.b, p.style.a)
ellipse(p.style.x * 2, p.style.y * 2, p.style.radius * 2, p.style.radius * 2)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment