Itt vagyok. Rövid leszek de érthetetlen, ahogy azt már mindenki megszokta. Foglalkozzunk mondjuk egy kis tűz effekttel. Szóval jöjjön az alcím:
 
Fire Effekt
 

 
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 ds
end;

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.

 
 Kimmel Tamás
eMail:PC-XUser@FREEMAIL.C3.HU, Subject: "ABC"