If you're seeing this message, it means we're having trouble loading external resources on our website.

Jeżeli jesteś za filtrem sieci web, prosimy, upewnij się, że domeny *.kastatic.org i *.kasandbox.org są odblokowane.

Główna zawartość

Pojedyncza cząsteczka

Przed utworzeniem ParticleSystem musimy utworzyć obiekt opisujący pojedynczą cząsteczkę. Ale jest dobra wiadomość: już to zrobiliśmy. Nasz obiekt Mover z sekcji Siły jest doskonałym wzorcem. W naszym przypadku cząsteczka jest niezależnym ciałem poruszającym się po ekranie. Ma położenie, prędkość, przyspieszenie, konstruktor do inicjalizacji tych zmiennych i funkcje display() do wyświetlania i update() do aktualizacji swojego położenia.
// Prosty obiekt typu Particle
var Particle = function(position) {
  this.acceleration = new PVector();
  this.velocity = new PVector();
  this.position = position.get();
};

Particle.prototype.update = function(){
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
};

Particle.prototype.display = function() {
  stroke(0, 0, 0);
  fill(175, 175, 175);
  ellipse(this.position.x, this.position.y, 8, 8);
};
To jest najprostszy możliwy przykład cząsteczki. W tym momencie możemy rozwinąć nasz model cząsteczki w kilku różnych kierunkach. Moglibyśmy dodać metodę applyForce() by wpłynąć na zachowanie cząsteczki (w późniejszym przykładzie będziemy robić dokładnie to). Moglibyśmy dodać zmienne opisujące kolor i kształt albo użyć metody image() by narysować tą cząsteczkę. Na razie jednak skupmy się na dodaniu jednego szczegółu: czasu życia.
Typowe układy cząsteczek obejmują coś zwane emiterem. Emiter jest źródłem cząsteczek i kontroluje ich początkowe parametry (położenie, prędkość, itd.). Emiter może tworzyć pojedynczą chmurę cząsteczek, ciągły ich strumień albo oba. Chodzi o to, że w typowej implementacji, takiej jak ta, cząsteczka zostaje utworzona przez emiter ale nie istnieje w nieskończoność. Gdyby trwała w nieskończoność, nasz program zatrzymałby się ponieważ liczba cząsteczek zwiększyłaby się do gigantycznych rozmiarów wraz z upływem czasu. Wraz z tworzeniem się nowych cząsteczek musimy upewnić się że stare ulegają zniszczeniu. To tworzy iluzję nieskończonego strumienia cząstek jednocześnie nie wpływając na wydajność naszego programu.
Istnieje wiele różnych sposobów aby zdecydować kiedy cząsteczka ulega zniszczeniu. Na przykład może wejść w styczność z innym obiektem albo po prostu opuścić powierzchnię ekranu. Jednakże naszemu pierwszemu obiektowi typu Particle dodamy atrybut timeToLive. Atrybut ten będzie działał jak licznik, odliczający od 255 do 0, gdy wartość tego licznika osiągnie 0 będziemy traktować tą cząsteczkę jako "martwą". Rozszerzmy więc obiekt Particle w następujący sposób:
// Prosty obiekt typu Particle
var Particle = function(position) {
  this.acceleration = new PVector();
  this.velocity = new PVector();
  this.position = position.get();
  this.timeToLive = 255;
};

Particle.prototype.update = function(){
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.timeToLive -= 2;
};

Particle.prototype.display = function() {
  stroke(255, 255, 255, this.timeToLive);
  fill(127, 127, 127, this.timeToLive);
  ellipse(this.position.x, this.position.y, 8, 8);
};
Powodem dla którego wartość timeToLive jest ustawiona na 255 i odlicza do 0 jest wygoda. Mając taki zakres wartości możemy użyć timeToLive również jako przezroczystości alfa dla elipsy. W momencie gdy cząsteczka staje się “martwa” znika z ekranu.
Po dodaniu atrybutu timeToLive będziemy nam potrzebna dodatkowa metoda — funkcja która zwraca true lub false w zależności od tego czy dana cząsteczka jest martwa lub nie. Metoda ta przyda się gdy będziemy implementować obiekty typu ParticleSystem których zadaniem będzie zarządzanie listą cząsteczek. Napisanie tej funkcji jest łatwe; powinna po prostu zwracać true, jeśli wartość timeToLive jest mniejsza od 0.
Particle.prototype.isDead = function() {
  return this.timeToLive < 0;
};
Zanim przejdziemy do tworzenia większej ilości cząsteczek warto upewnić się że nasza cząsteczka działa prawidłowo i utworzyć szkic z jednym obiektem typu Particle. Pełny kod znajduje się poniżej z dwoma małymi uzupełnieniami. Dodajemy metodę run() która po prostu wywołuje metody update() i display() za nas. Dodatkowo nadaliśmy cząsteczce losową prędkość początkową oraz przyspieszenie skierowane w dół (w celu symulowania grawitacji).
Teraz mamy obiekt opisujący pojedynczą cząsteczkę, możemy więc przystąpić do kolejnego, dużego kroku. W jaki sposób możemy śledzić stan wielu cząsteczek gdy nie możemy określić maksymalnej ilości cząsteczek w danym czasie?