Fire has fascinate men since the time of cavemen. Instead of reproducing it by banging two
rocks together, let's simulate it by pushing pixels.
The fire effect is a relatively simple one and looks good when done right.
I remember the first time I heard about and saw the fire effect. Two guys
were arguing on Omicron Theta (a great BBS that went down in 1996) about
who could code the faster and better fire. I downloaded both and they
absolutly amazed me! I couldn't figure out how it was done. Another two
years went by and I finally taught myself enough stuff to do demo coding.
I look at some tutorials from the
Hornet Archive and read over the
theory behind it. It also helped to see some code to see how it was
actually done. Most of the source out there is in assembler, which is good
for a nice, fast effect, but I found that it was very confusing to figure
out what was going on. I found some C source and that made everything much
easier to understand. I liked the fire effect so much that I used it as a
common element in our first demo ;)
The fire effect consists of two parts, the seed and the blur. The
palette also plays a big part in this. The fire effect is really just an
averaging routine. If we take four numbers and average them, we will get a
number that is less than the greatest value put in.
For example, averaging 1,2,3 will give us (1+2+3)/3 = 2, and if we consider
these values to be degrees of "hotness", then averaging the hot
colors with the surrounding colors will gives us the resulting mixed color.
This is the main idea behind the fire effect.
The palette is set up with a gradient, with 0 being the "coolest" color
and 255 being the "hottest" color. In a typical fire, 0 is black, 255 is white,
and a gradient of black to red to yellow to white is between 0 and 255.
Next we "seed" the bottom few lines of our double buffer with
white (255). We also place a few lines with random colors to help create
turbulence in the fire. For each pixel we find the average value of the pixels
around it and plot the average value to the screen. This means that when we get
a really "hot" pixel (255) and average it with some cooler pixels (23, 56, 98),
then the pixel will cool down (to 208). We move it up on the screen to make the
flames move towards the sky. If we do this for every pixel we get a fire!
The basic algorithm goes like this:
while(!kbhit())
{
fill bottom of double buffer with white and random colors
for(y = 0; y < 200; y++)
{
for(x = 0; x < 320; x++)
{
average the colors
plot the average color 1 pixel above the current pixel
}
}
copy everything except the bottom "seed" lines to the screen
}
This program uses a double buffer, which is an area in RAM to which all the
drawing is done and then is copied to the screen. This allows you to do all
the messy work in one place (such as averaging all the pixels and replotting
them) and show the final result on the screen.
I purposely removed most of the optimizations for sake of clarity.
Things to try:
The zip file includes the executable fire effect plus the source code, which
has been heavily commented, as well as this tutorial that you're reading right
now.