Заведем два массива 1 и 2 - один массив будет содержать текущий кадр
пламени,а во второй мы будем заносить результаты вычислений. Создадим
палитру пламени от 250 до 100 это будет сплошной белый цвет - пламя в
очаге. Далее белый, плавно проходя через желтый, перейдет в красный и
черный. Эту палитру можете посмотреть если определен Debug.
В чем состоит основа алгоритма - для каждой точки из массива 1, мы
делаем следующее : берем сумму всех окружающих ее точек и делим на их
количество. Для хорошего качества точек берем 8. Что же получается?
Если очаг пламени организовать внизу, т.е. внизу на каждом шаге
случайно ставить точки с большим значением, усреденные суммы дадут
нужное затухание. Т.к. мы ставим в очаге точки случайно , то появляются
красивые языки.
Последовательность действий:
Массив 1 содержит текущий кадр пламени.
Создаем в массиве 1 внизу случайные очаги ( просто ставим точки)
Каждый элемент массива 2 получаем как усреденную сумму, соответствующих элементов окружающий данный в массиве 1
Type PFireMem = ^TFireMem; TFireMem = Array[0..201,0..319] Of Byte; Var FireMem : PFireMem; I,J : Integer; R,G,B,dR,dG,dB : Real;
Procedure PlotFireHead; Var I : Integer; Begin For I := 0 To 319 Do If Random( 2) = 1 Then Begin FireMem^[ 199] [ I] := 255; FireMem^[ 198] [ I] := 255; End; End;
Begin InitDemoPart; GetMem( FireMem, 65000); R := 0; G := 0; B := 0; dR := 0.63; dG := 0.91; dB := 1.5; For I := 1 To 100 Do Begin SetRGBColor( I, Round( R), Round( G), Round( B)); R := R + dR; If I > 30 Then G := G + dG; If I > 60 Then B := B + dB; End; For I := 100 To 250 Do SetRGBColor( I, 60, 60, 60); {$IFDEF DEBUG} For I := 1 To 100 Do For J := 1 To 100 Do Mem[$A000: J * 320 + I] := I; ReadKey; {$ENDIF} FillChar( FireMem^, 65000, 0); Repeat PlotFireHead; FireLoop; Move( DBuffer^, FireMem^, 64000); Move( DBuffer^, Ptr( $A000, 0)^, 64000-320*4); Until KeyPressed; ReadKey; FreeMem( FireMem, 65000); RestoreDemo; End;