To make fire in a pixel grid, the basic idea is that, we traverse each pixel and update each pixel above them to be “cooler”. And we do it over and over again. This way, if we set all bottom line of pixels to “hottest”. we can see just sit and let it grow up. Like this:
If we make it bigger and put fire's color on it, based on the number. It looks like this.
But that doesn’t really look like fire, it’s too “linear”. The trick to make it look like fire is adding some randomness on how the fire “grow” up.
First, instead of always make the above pixel “cooler”, we only do it by 50% chance. So 50% chance the above pixel will be cooler, and 50% the above pixel won't change. It looks like this:
It looks better. Next, when we look for the above pixel, instead of going straight up, we can add a shift to left or right randomly. In code, when we traverse each pixel, find the pixel above, then either, update that pixel, or update the one on its left, or update the one on its right. The result looks like this:
Now it starts to look like fire. Let's try to add more pixels and render it on canvas instead of HTML to get a better performance. We will also get ride of the pixel border and number.
In the original article, the author left an exercise for readers to simulate wind. If you get the idea how the fire is generated, it’s pretty straight forward to know wind can be simulated. All we need to do adjust the shift of left or right when update the above pixel. If we shift more to the left, it will cause the pixel leaning toward left, which makes it look like there is a wind blow from right to left. And the same goes to the other way.
Fading the fire can be simulated by gradually updating the bottom section of the pixel to be “cooler”. It will not only “fade” the bottom section but also “fade” all the pixels above, because they are propagated.
Fire intensity basically means how long does it take for a pixel to get “cool down” as it propagates up. Currently, we set it to be 50% chance to cool down. So if we want the fire to be more “intense”, we just need to make let less possible to cool down.
You can try to control the fire here:
You can find the source code at https://github.com/GingerBear/doom-fire