Ez egy nagyon egyszerű kis cucc. Egy olyan valami ami a tűzhoz kellene hogy hasonlítson. Ehez első nekifutásra egy olyan palettát kell összehozni, amiben erősödő vörös-sárga árnyalatok tobzódnak. Valami ilyesmit:

procedure initpal; var n: integer;begin   palette[0].R:=0;palette[0].G:=0;palette[0].B:=0;   for n:=1 to 32 do begin palette[n].R:=2*n-1;palette[n].G:=0;palette[n].B:=0;end;   for n:=33 to 160 do begin palette[n].R:=63;palette[n].G:=(n-33) div 2; end;   for n:=129 to 255 do begin palette[n].R:=63;palette[n].G:=63;palette[n].B:=(n-129) div 2;end; end;

Ha ezzel megvagyunk, attól ugye még semmi nem fog történni. Szóval most egy kis elméletnek kéne jönni, hogyan lehet lemodellezni a tüzet. Csakhogy ennek nem sok köze lesz a modellezéshez, egszerűen így lehet megcsinálni.

Az az egész lényege, hogy minden pont színintenzitását az alatta(-mellette) lévő pontok színének átlagával határozzuk meg. Ez azért jó mert így a tűz tényleg felfelé fog halványodni, azonkívül csóvák fognak kialakulni hiszen, ha egy pont színe erősebb a többinél a feltte lévőké is erősebb lesz. Azonban ha csak ezt a dolgot játszanánk, akkor a színek egyer csak elfogynának, hiszen ha mindig csak átlagolunk, akkor egy idô után mindegyik pont fekete lesz. Hogy a tűz tényleg égjen, és ne csak halványodjon, mindig ujabb magas színű (hot points) pontokat kell bevinni az alsó sorba, innen pedig a lángok az átlagolás következtében elindulnak. Ezeket a pontokat persze véletlenszerűen kell bevinni, és szépen fog lobogni.

A gyakorlati megvalósításnál két tömböt kell használnunk, mert amelyikbe írjuk az új pontok színét nem lehet ugyanaz, mint amelyikből a régieket olvassuk. Ez világos. Miután pedig kiszámoltuk az új pontok színét vissza kell írni őket a régieket tartalmazó tömbbe, mert legközelebb már ezek a pontok lesznek a régiek.

Lássuk:

procedure comp; var n,t: integer; b:^byte;begin   for n:=1 to spots do  begin     longint(b):=longint(buf1)+width*(height-1)+random(width);         {also sor veletlenszeru feltoltese}     b^:=255;  end;   asm     push es     push ds     les di,buf2 {es:di-> buf2}     lds si,buf1 {ds:si-> buf1}     mov dx,height {dx=sorok}   @sorok:     mov cx,width-2 {cx=oszlopok (a ket szelet kihagyjuk)}   @oszlopok:     xor ax,ax {atlagoljuk a pontokat:}     xor bx,bx     mov al,[si+width+1] {egy sorral lejjebb jobbra}     mov bl,[si+width-1] {egy sorral lejjebb balra}     add ax,bx     mov bl,[si+1] {jobbra}     add ax,bx     mov bl,[si-1] {balra}     add ax,bx     mov bl,[si+width] {lefele}     add ax,bx     mov bl,[si+2*width-1] {ket sorral lejjebb balra}     add ax,bx     mov bl,[si+2*width+1] {ket sorral lejjebb jobbra}     add ax,bx     mov bl,[si+2*width] {ket sorral lejjebb}     add ax,bx     shr ax,3 {8 pont osszege 8-al osztva (ATLAG az ax-ben!!!)}     mov es:[di],al {a pont szine a 8 pont atlaga lesz}     inc si     inc di     loop @oszlopok     add si,2 {szeleket kihagyjuk}     add di,2     dec dx     jnz @sorok     pop ds     push ds {visszamasoljuk a regi tombbe}     les di,buf1     lds si,buf2     mov cx,height*width/2     rep movsw {buf1<-buf2}     pop ds     pop es  end; end;
Aztán az egyik tömböt csak ki kell nyomatni a videomemóriába:
procedure dump;assembler;asm   push ds   push es   mov ax,0a000h   mov es,ax   lds si,buf1   mov di,Fx+Fy*width   mov cx,(height-4)*width/2   rep movsw   pop es   pop dsend;
Ezt a két függvényt pedig egymásután futtatgatjuk.
repeat   comp;   dump; until keypressed;

Azt hiszem ez egy elég egyszerű téma volt. Gondolom mindenki érti, nem is magyarázok tovább. A forráskód pascalos assemby-ben lett megszülve, így remélem mindenki meg tudja emészteni. A progi egy egy képernyő széles 100 pixel magas tüzet próbál szimbolizálni. Szerintem hasonlít. (Mondjuk még nem láttam égni a monitorom, de ki tudja...) Persze akinek más a gusztusa a paletta átírásával, vagy a hot point-ok színének, számának variálásával, eléggé lehet vadítani.

Most már abbafejezem.