"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:
![](fire.png)
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:
![](fire2.png)
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="myCanvas" width="1000" height="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 intid= setInterval (plomien, 50); // 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))*10, 10, 10); |
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