Inspired by the excellent write-up at: https://fabiensanglard.net/doom_fire_psx/
Essentially a bottom-to-top cellular automata, with just the right amount of randomness. The key is spreadFire
which moves pixel values up and left while decreasing the color value. The use of an indexed palette makes this algorithm especially simple.
const ra = require('raster');
ra.setSize({w: 256, h: 110});
ra.setZoom(2);
ra.palette.setRGBMap(ra.mixColors([ 0, 0x000000,
16, 0xff0000,
32, 0xff8800,
44, 0xffff00,
48, 0xffffff]));
// Create fuel along the bottom
ra.setColor(47);
ra.drawLine(0, ra.height-1, ra.width, ra.height-1);
ra.run(function() {
ra.fillFrame({traverse: 'columnar'}, spreadFire);
});
function spreadFire(x, y) {
let rand = Math.round(Math.random() * 3) % 4;
let val = ra.get(x, y) - (rand % 2);
if (val < 0) { val = 0; }
ra.put(x - rand + 1, y - 1, val);
}