"Płomienie" - efekt graficzny w JavaScript





Ogień, który widzisz powyżej, to efekt graficzny, który był popularny w latach 90-tych.

Nadal wygląda świetnie, a dzięki łatwej matematyce i zwięzłości (około 20 linii JavaScript), jest to dobre ćwiczenie w programowaniu.

W skrócie: tworzymy tablicę złożoną z pól. Im wyższa wartość pola, tym jaśniejszy jego kolor. W każdej klatce animacji przypisujemy losowe wartości polom w najniższym widzialnym rzędzie, a wartości pozostałych pól obliczamy na podstawie niższych rzędów. Mówiąc dokładniej, najpierw dodajemy wartości trzech pół bezpośrednio poniżej oraz pola dwa wiersze niżej:



X jest polem, które obliczamy, a 1,2,3 i 4 to pola, których wartości uwzględniamy w obliczeniach. Następnie dzielimy tę sumę czterech pól przez wartość nieco wyższą niż 4, na przykład 4,1. To powoduje, że płomienie przygasają w górze.

Wszystkie pola rysujemy w każdej klatce. Aby to zrobić, musimy zamienić indeks tablicy na współrzędne ekranowe. Ponieważ JS nie ma 2-wymiarowych tablic, ta konwersja jest nieco niezręczna.

Oto indeksy wszystkich pól przykładowej tablicy z pięcioma kolumnami i 6 rzędami. Pierwsze pole jest w lewym dolnym rogu:



Najniższy rząd (elementy 0-4) będzie zawsze pusty.
Wartości pól w drugim rzędzie od dołu (elementy 5-9) będą losowane w każdej klatce, by podsycać ogień.
Wszystkie pozostałe rzędy (elementy 10-29) będą obliczane.
Oto kod z dodatkowymi objaśnieniami. Miłej zabawy!

<html>
<body bgcolor="black">
<canvas id="myCanvaswidth="1000height="800"></canvas><br>
 
<script>
const wysokosc=80;    // liczba rzędów
const szerokosc=100;   // liczba kolumn
let ogien=[]; // tablica wartości wszystkich pól
 
for (let i=0;i<wysokosc*szerokosc;i++) ogien[i]=0// czyścimy tablicę
 
let intidsetInterval (plomien50); // funkcja "plomien" będzie uruchamiana co 50 milisekund
let context = document.getElementById('myCanvas').getContext('2d');
 
function plomien() {
        for(i=0;i<szerokosc;i++)
                ogien[i+szerokosc]=Math.floor(Math.random()*255); // losujemy wartości drugiego rzędu od dołu
 
        for(let y=wysokosc;y>1;y--)           // każdy rząd
                for(let x=0;x<szerokosc;x++) {  // każda kolumna
                        i=y*szerokosc+x;   // zamiana współrzędnych x i y na indeks tablicy
                        ogien[i]=Math.floor((                // dodajemy wartości pól:
                        ogien[(y-1)*szerokosc+        (x-1+szerokosc)%szerokosc]+ // w lewo i w dół
                        ogien[(y-1)*szerokosc+        (x  +szerokosc)%szerokosc]+ // bezpośrednio poniżej
                        ogien[(y-1)*szerokosc+        (x+1+szerokosc)%szerokosc]+ // w prawo i w dół
                        ogien[(y-2)*szerokosc+        (x  +szerokosc)%szerokosc]  // dwa rzędy w dół
                        )/4.04);}   // dzielenie, by obniżyć wartości w górnej części płomieni
 
        for(i=szerokosc*4;i<szerokosc*wysokosc;i++) {        // teraz rysujemy ogień na ekranie
                color=ogien[i].toString(16);        // zamiana wartości dziesiętnej na szestnastkową
                context.beginPath();        // zamiana indeksu i na współrzędne ekranowe i rysowanie prostokąta
                context.rect((i%szerokosc)*10, (wysokosc-Math.floor(i/szerokosc))*101010);
                context.fillStyle ='#'+color+'0000';  // wartość pola staje się czerwonym składnikiem koloru.
                context.fill();
                }
        }
 
</script>
</body>
</html>




Inne samouczki:

JavaScript:

Fraktale - 25 linii


Złudzenie optyczne - 18 linii


Sinus scroll w stylu 8-bitowych demo - 30 linii


Gra Saper (Minesweeper) - 100 linii


Python (Blender 3d):

Rozbiajanie muru kulą - 14 linii


Efekt domino - 10 linii




English version of this tutorial