Instantly share code, notes, and snippets.

# joshski/flame.lua Created Apr 21, 2013

What would you like to do?
Generates a little flame. Works in Codea.
 -- 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