Împușcați stelele cu motorul Stardust Particle

În acest tutorial vă voi prezenta motorul Stardust Particle. În primul rând vă voi arăta cum să înființați Stardust, iar apoi voi acoperi responsabilitățile de bază ale Stardust și modul în care acestea colaborează împreună pentru ca Stardust să funcționeze ca un întreg.

Apoi, ne vom uita la fluxul general de lucru al lui Stardust și vom ajunge la crearea unui efect de particule cu stelele care se aruncă de pe cursorul mouse-ului; stelele vor încetini treptat, vor crește mai mari după naștere și se vor micsora când vor muri.

În cele din urmă, voi demonstra flexibilitatea Stardust creând mai multe variante de la exemplul deja complet, inclusiv folosind clipuri video animate ca particule, interval de timp pentru simularea variabilelor de particule și filmarea obiectelor de afișare de diferite clase de la un singur emițător.

Acest tutorial este destinat persoanelor care sunt deja familiarizate cu programarea orientată pe obiecte ActionScript 3.0 (OOP), așa că presupun că deja știți foarte bine ce înseamnă clase, obiecte, moștenire și interfață. Nici o problema cu OOP? Atunci hai să tragem niște stele!




Stardust Particle Engine

După cum sugerează și numele, Stardust este folosit pentru crearea efectelor particulelor. Dacă sunteți un ActionScriptor cu experiență, s-ar putea să fi creat efectele particulelor de la zero de mai multe ori și să spuneți "Sunt complet cool cu ​​crearea efectelor particulelor de la zero, de ce aș avea nevoie oricum de un motor cu particule?" Stardust este aici pentru a vă ajuta să vă concentrați mai mult pe designul comportamentului fizic al particulelor decât să vă faceți griji cu privire la lucrurile de nivel inferior, cum ar fi gestionarea memoriei. În loc să scrieți codul pentru a avea grijă de datele despre particule, inițierea și eliminarea resurselor, cu Stardust, puteți trece peste aceste rutine plictisitoare și doar decideți cum doriți să se comporte particulele dvs..

Stardust Caracteristici

Structura de clasă a Stardust a fost inspirată de sistemul FLiNT Particle System, un alt motor cu particule ActionScript 3.0. Astfel, aceștia împărtășesc câteva trăsături de bază similare.

  • Efecte particulare 2D și 3D - Stardust poate fi folosit pentru a crea atât efecte de particule 2D cât și 3D. Are propriul motor 3D încorporat și poate fi folosit și pentru a lucra în combinație cu alte motoare 3D din cele trei particule, inclusiv ZedBox, Papervision3D și ND3D.
  • Extensibilitate ridicată - Stardust oferă un set mare de comportamente și randamente de particule la dispoziția dumneavoastră. Dacă niciuna dintre ele nu corespunde nevoilor dvs., puteți întotdeauna să extindeți clasele de bază și să vă creați propriile comportamente de particule personalizate; de asemenea, vă puteți crea propriul renderer pentru a lucra cu un alt motor 3D care nu este suportat de Stardust.

În plus față de aceste caracteristici de bază, Stardust oferă și câteva caracteristici avansate pentru utilizatorii experimentați.

  • Timescale de simulare reglabilă - Timpul utilizat pentru simularea particulelor poate fi reglat dinamic în timpul perioadei de execuție. De exemplu, dacă schimbați intervalul de timp la jumătate din original, efectul de particule va fi pe jumătate mai rapid decât viteza normală; și dacă optimizați intervalul de timp de două ori mai mult decât originalul, efectul de particule va fi simulat de două ori mai rapid decât normal. Această caracteristică poate fi utilă atunci când creați un joc care are efecte încetinite: efectul de particule poate încetini pentru a se potrivi cu viteza motorului dvs. de joc, sincronizând cu animația și grafica jocului.
  • Serializarea XML - Puteți transforma sistemul de particule într-un fișier în format XML care poate fi stocat pe hard disk, încărcat ulterior în timpul executării și interpretat pentru a vă reconstrui sistemul de particule origene. Acest lucru este foarte util atunci când lucrați cu un proiect mare. Spuneți că doriți doar să vă măriți puțin particulele, astfel încât să modificați parametrii din codul sursă și să recompilați întreaga aplicație Flash, ceea ce ar putea dura un minut sau chiar peste cinci minute dacă proiectul dvs. este extrem de mare. Merita? Absolut nu. E o pierdere totală de timp. Folosind caracteristica de serializare XML pentru a salva sistemul de particule în fișiere XML externe, separați parametrii de codul sursă pentru aplicația principală. Deci, ceea ce trebuie să faceți este să deschideți fișierul XML, să modificați valorile parametrilor, să îl salvați și să redeschideți aplicația principală. Asta e! Nu este necesară nicio recompilare. Aș spune că aceasta este modalitatea ideală de a lucra cu proiecte mari.

Când vine vorba de efectele particulelor, este foarte important să se gestioneze eficient datele particulelor masive. Stardust folosește în mare măsură bazinele de obiecte și listele asociate pentru a spori performanța:

  • Piscine pentru obiecte - Obiectele folosite sunt stocate într-un bazin; mai tarziu, daca un obiect de acelasi tip este necesar, Stardust nu il instanteaza imediat, ci verifica daca exista vreun obiect stocat anterior in pool-ul de obiecte stanga. Dacă da, Stardust pur și simplu scoate acel obiect și îl folosește, în loc să creeze un obiect complet nou. De obicei, efectele particulelor implică o instanțiere a obiectelor, care consumă CPU. Folosind piscinele de obiecte, Stardust reduce foarte mult instantația.
  • Linked Lists - Este foarte ușor și tentant să stocați datele particulare într-o matrice; totuși, într-un caz în care particulele sunt create și îndepărtate foarte frecvent, au loc multe îmbinări de matrițe pentru a elimina particulele moarte. Matrițarea matricei este un proces consumator de procesoare, în special pentru matrice lungi. Pentru o listă legată, indiferent de lungimea listei, durează mereu același timp scurt pentru a strânge particule moarte. Din versiunea 1.1, Stardust a început să utilizeze listele interne pentru stocarea datelor despre particule.

Setarea Stardust

Înainte de a ajunge la o codificare reală, va trebui să luăm o copie a Stardust Particle Engine. Este lansat sub licență MIT, ceea ce înseamnă că este total gratuit, indiferent dacă doriți să îl utilizați într-un proiect comercial sau necomercial.

Iată pagina de pornire a proiectului Stardust: http://code.google.com/p/stardust-particle-engine/

Puteți descărca Stardust aici: http://code.google.com/p/stardust-particle-engine/downloads/list

La momentul redactării, ultima versiune care poate fi descărcată din lista de descărcări este 1.1.132 Beta. Puteți lua întotdeauna cea mai recentă revizuire din depozitul SVN (care ar putea să nu fie stabilă, cu toate acestea).

Pe pagina de pornire a proiectului puteți găsi și alte accesorii, cum ar fi documentația API și o copie a manualului PDF. Există chiar tutoriale video pe YouTube.

Responsabilități de clasă Stardust

Aici voi trece pe scurt clasele de bază Stardust și responsabilitățile lor.

StardustElement

Această clasă este superclajul tuturor claselor de bază, care definește proprietățile și metodele, în special pentru serializarea XML.

Întâmplător

În general, efectele particulelor privesc controlul unei cantități de entități cu un aspect similar și comportament similar, dar randomizat. Clasa Random este pentru generarea numerelor aleatoare, care pot fi folosite în Stardust pentru a randomiza proprietățile particulelor. De exemplu, clasa UniformRandom este o subclasă a clasei Random și numele său spune totul: numărul aleatoriu generat de un obiect UniformRandom este distribuit uniform și voi folosi această clasă în special pentru întregul tutorial.

Zona

Există momente când un număr aleator unidimensional nu este suficient. Uneori avem nevoie de numere aleatorii bidimensionale, care sunt în esență perechi de numere aleatorii, pentru proprietăți precum poziția și viteza. Clasa Zone este pentru generarea de perechi de numere aleatoare bidimensionale. Această clasă modelează o pereche de numere aleatorii ca un punct aleator într-o zonă 2D. De exemplu, CircleZone generează perechi de numere aleatoare (x, y) de la puncte aleatorii dintr-o regiune circulară. Clasele Random și Zone sunt utilizate în principal de clasa Initializer, care va fi acoperită ulterior. Clasa Zone3D este omologul 3D al acestei clase, pentru efectele 3D ale particulelor.

emiţător

Clasa Emitter este în principiu în cazul în care toate lucrurile de nivel scăzut sunt încapsulate. Un emițător inițiază particule nou create înainte de a fi adăugate în simulare, actualizează proprietățile particulelor în fiecare iterație de buclă principală și elimină particule moarte din simulare. Metoda Emitter.step () este ceea ce doriți să invocați în mod repetat, pentru a menține Stardust în funcțiune.

Ceas

Clasa Ceas determină viteza de creare a particulelor noi pentru emițători. Un obiect Emitter conține exact o referință la un obiect Ceas. La începutul fiecărui apel al metodei Emitter.step (), emițătorul cere obiectului ceas câte particule noi ar trebui să creeze. Luați în clasă SteadyClock, de exemplu, îi spune emițătorilor să creeze particule noi la o rată constantă.

initializatorul

Această clasă este pentru inițializarea particulelor nou create. Un obiect inițializator trebuie adăugat la un emițător pentru ca acesta să funcționeze. Practic, o subclasă de inițializator inițializează numai o proprietate a particulelor. De exemplu, clasa de inițializare a masei inițiază masa de particule noi. Unii inițializatori acceptă un obiect Rand ca parametru constructor pentru inițializarea particulelor cu valori aleatorii. Următorul cod creează un inițializator de viață care inițializează durata de viață a particulelor la valori centrate la 50 cu variație de 10, și anume între intervalul de la 40 la 60.

 Viața nouă (noul UniformRandom (50, 10));

Acțiune

Obiectele de acțiune actualizează proprietățile particulelor în fiecare iterație a bucla principală (metoda Emiter.step ()). De exemplu, clasa de acțiune Mută ​​actualizează pozițiile particulelor în funcție de viteză. Un obiect de acțiune trebuie adăugat unui emițător pentru ca acesta să funcționeze.

Generarea fluxului de lucru Stardust

Acum că știți cum colaborează clasele de bază, să aruncăm o privire la un flux general de lucru pentru Stardust.

Începeți prin a crea un emițător. Utilizați clasa Emitter2D pentru efectele particulelor 2D și clasa Emitter3D pentru efecte 3D.

 var emitter: emitorul = noul Emitter2D ();

Pentru a specifica viteza de creare a particulelor, avem nevoie de un ceas. Acest lucru poate fi setat fie de proprietatea Emitter.clock, fie prin trecerea unui ceas ca prim parametru la constructorul emițătorului.

 // abordare proprietate emitter.clock = noul SteadyClock (1); // abordare constructor var emitter: Emitter = nou Emitter2D (nou SteadyClock (1));

Adăugați inițializatorii la emițător prin metoda Emitter.addInitializer ().

 emitter.addInitializer (noua viață (noul UniformRandom (50, 10))); emitter.addInitializer (noua Scară (noul UniformRandom (1, 0,2)));

Adăugați acțiuni la emițător prin metoda Emitter.addAction ().

 emitter.addAction (noua mișcare ()); emitter.addAction (nou Spin ());

Creați un renderer și adăugați emițătorul la redare prin metoda Renderer.addEmitter ().

 var renderer: Renderer = noul DisplayObjectRenderer (container); // "container" este containerul nostru sprite renderer.addEmitter (emitter);

În cele din urmă, apelați în mod repetat metoda Emitter.step () pentru a menține simularea particulelor. S-ar putea să doriți să utilizați evenimentul enter-frame sau un cronometru pentru a face acest lucru. Într-o singură chemare a metodei Emitter.step (), ceasul determină câte particule noi ar trebui create, aceste particule noi sunt inițializate de inițializatori, toate particulele sunt actualizate prin acțiuni, particulele moarte sunt îndepărtate și, în cele din urmă, redarea redă efectul particulei.

 // abordarea evenimentului enter-frame addEventListener (Event.ENTER_FRAME, mainLoop); // Timer abordare timer.addEventListener (TimerEvent.TIMER, mainLoop); funcția mainLoop (e: Eveniment): void emitter.step (); 

În regulă. Asta e destul de mult pentru Stardust. Acum este momentul să deschideți IDE-ul Flash și să vă murdăriți mâinile.

Pasul 1: Creați un nou document Flash

Creați un nou document Flash cu o dimensiune de 640X400, o rată a cadrelor de 60fps și un fundal întunecat. Aici am făcut un fundal de gradient albastru închis. Apropo, Stardust funcționează bine atât cu Flash Player 9 și 10, deci este în regulă indiferent dacă utilizați Flash CS3 sau CS4. În acest tutorial voi folosi Flash CS3.

Pasul 2: Desenați o stea

Creăm un efect de particule cu stele, așa că va trebui să desenați o stea și să o convertim într-un simbol, exportat, firește, pentru ActionScript. Acest simbol va fi folosit mai târziu pentru a face efectul nostru de particule. Denumiți simbolul și clasa exportată "Star".

Pasul 3: Creați Clasa de documente

Creați o nouă clasă de documente și numiți-o StarParticles.

 pachet import flash.display.Sprite; public class StarParticles extinde Sprite funcția publică StarParticles () 

Pasul 4: Extindeți emițătorul

După cum sa menționat în fluxul general de lucru, primul pas este crearea unui emițător. Următorul pas este să adăugați inițiale și acțiuni către emițător. În timp ce acest lucru se poate face în constructorul de clase de documente, recomand insistent ca acesta să se facă într-o subclasă separată a emițătorului. Este întotdeauna mai bine să separăm designul de comportament al particulelor din programul principal; prin aceasta, codul este mult mai curat și mai ușor de modificat în viitor, fără a fi amestecat cu programul principal.

Vom crea un efect de particule 2D, astfel încât Emitter2D este clasa emițător pe care o vom extinde. Extindeți clasa Emitter2D și numiți-o StarEmitter, deoarece vom încerca să împușcăm stele mai târziu. Constructorul emițător acceptă un parametru Ceas, deci vom declara un parametru constructor pentru a transmite o referință de obiect Ceas la constructorul superclass.

 pachet import idv.cjcat.stardust.twoD.emitters.Emitter2D; clasa publică StarEmitter extinde Emitter2D funcția publică StarEmitter (ceas: ceas) // trece pe obiectul ceasului super constructor super (ceas); 

Pasul 5: Declarați constantele

O abordare mai bună pentru a crea o subclasă a emițătorului este de a declara parametrii particulelor ca fiind constante statice, grupate într-un singur loc. Deci, în cazul în care doriți să modificați parametrii, veți ști întotdeauna unde să găsiți declarațiile. Semnificația acestor constante va fi explicată mai târziu când vor fi folosite.

 // durata medie de viață statică const LIFE_AVG: Number = 30; // variație de viață statică statică const LIFE_VAR: Number = 10; // scara medie statică privată const SCALE_AVG: Number = 1; // variația scalei private static const SCALE_VAR: Number = 0.4; // scară timp de creștere statică statică const GROWING_TIME: Number = 5; // scară timp scadere privat static const SHRINKING_TIME: Number = 10; // viteza medie statică statică const SPEED_AVG: număr = 10; // variația vitezei const static privat const SPEED_VAR: Number = 8; // medie de omega (viteză unghiulară) statică statică privată OMEGA_AVG: Number = 0; // omega variație privată statică const OMEGA_VAR: Number = 5; // coeficient de amortizare const static privat DAMPING: Number = 0.1;

Pasul 6: Adăugarea inițializatorilor

Ce inițializatori trebuie să creăm efectul nostru de particule? Să aruncăm o privire la lista de mai jos:

  • DisplayObjectClass - Acest inițializator atribuie unui obiect de afișare specificat fiecărei particule, care va fi utilizat de către un DisplayObjectRenderer pentru a face efecte particulare. Constructorul acceptă o referință de clasă la clasa de obiecte de afișare pe care dorim să o instanțiăm; pentru acest tutorial, această clasă va fi clasa Star (simbolul) pe care am creat-o în pasul 2.
  • Viaţă - Acest inițializator atribuie fiecărei particule o valoare de viață aleatorie. Mai târziu, vom adăuga acțiuni la emițător pentru a epuiza această valoare a vieții în timp și pentru a marca o particulă ca moartă dacă valoarea ei de viață ajunge la zero. Un obiect random este transmis constructorului, care va fi folosit de acest inițializator pentru a genera o valoare aleatorie pentru durata de viață a particulelor. În majoritatea cazurilor, clasa UniformRandom este convenabilă și suficientă; primul parametru al constructorului UniformRandom este valoarea centrală (sau medie) a numerelor aleatoare generate, iar a doua este raza (sau variația). De exemplu, un obiect UniformRandom cu centrul 20 și variația 5 generează numere aleatorii în intervalul [15, 25]. Aici folosim constanta LIFE_AVG pentru valoarea centrala si LIFE_VAR pentru raza.
  • Scară - Ca inițializatorul de viață, inițializatorul scalei inițializează scala unei particule la o valoare aleatoare, determinată de un obiect Randat trecut la constructorul inițializatorului. Aici folosim constanta SCALE_AVG pentru valoarea centrala si SCALE_VAR pentru raza.
  • Poziţie - Acest inițializator atribuie unei particule o poziție aleatorie. Spre deosebire de inițiatorii Life și Scale, care au nevoie doar de numere aleatorii 1D, inițializatorul poziției necesită generatoare de perechi de numere aleatoare 2D. După cum este descris în secțiunea Responsabilități clasă Stardust, clasa Zone este exact în acest scop. Obiectul Zone transferat la constructorul inițializatorului este utilizat pentru a genera perechi de numere aleatoare 2D, care vor fi atribuite particulelor ca vectori de poziție. În acest tutorial vom face ca stelele să tragă dintr-un singur punct situat la cursorul mouse-ului, așa că vom folosi o clasă SinglePoint, care este o subclasă Zone. Pentru a ajusta dinamic coordonatele acestui obiect SinglePoint din clasa de documente, trebuie să expunem o referință la acest obiect de punct printr-o proprietate publică. Aceasta este ceea ce înseamnă proprietatea "punct".
  • Viteză - La fel ca inițializatorul poziției, inițializatorul de viteză are nevoie de un obiect Zone pentru a genera perechi de valori 2D aleatorii pentru a inițializa vitezele particulelor. Un vector 2D generat de obiectul Zone, care este coordonatul unui punct aleator în zonă, este atribuit particulelor ca viteze. Aici folosim clasa LazySectorZone care reprezintă o regiune sectorială. Un sector este o porțiune a unui cerc închis de două raze și două unghiuri. Pentru LazySectorZone, cele două unghiuri sunt implicit 0 și 360, reprezentând un unghi complet în jurul unui cerc. Primul parametru constructor al clasei LazySectorZone este media celor două raze, iar al doilea este variația razei. În acest caz, media celor două raze reprezintă viteza medie, iar variația razei reprezintă variația vitezei. Aici folosim constanta SPEED_AVG pentru primul parametru și SPEED_VAR pentru al doilea.
  • Rotație - Initializatorul de rotație inițializează un unghi de rotație al particulei la o valoare aleatorie. Și, întrucât unii dintre inițializatorii menționați anterior, constructorul acceptă un obiect Rand pentru a genera o valoare aleatorie. Deoarece am dori să avem particule cu unghiuri variind între 0 și 360 de grade, vom folosi 0 ca centru și 180 ca raza obiectului UniformRandom.
  • Omega - Omega, ca în majoritatea manualelor de fizică, înseamnă viteză unghiulară. Cu acest lucru, scopul acestui inițializator este clar: inițializează viteza unghiulară a unei particule la o valoare aleatorie, iar constanta OMEGA_AVG este folosită ca centru și OMEGA_VAR ca raza obiectului UniformRandom.

Iată codul:

 punct = nou SinglePoint (); addInitializer (noul DisplayObjectClass (Star)); addInitializer (noua viață (noul UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (noua scară (noul UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (noua poziție (punct)); addInitializer (noua Velocity (noua LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (noua rotație (nouă UniformRandom (0, 180))); addInitializer (noul Omega (noul UniformRandom (OMEGA_AVG, OMEGA_VAR)));

Pasul 7: Adăugarea de acțiuni

Bine, am terminat cu inițializatorii. Acum este momentul să adăugați acțiuni la emițător. Mai jos este o listă de acțiuni de care avem nevoie:

  • Vârstă - Efectul de vârstă scade valoarea de viață a particulei cu 1 în fiecare emițător.
  • DeathLife - Când valoarea de viață a unei particule atinge zero, această acțiune marchează particula ca moartă, schimbând proprietatea isDead de la false la adevărat. La sfârșitul etapei emițătorului, particulele moarte sunt îndepărtate.
  • Mișcare - Destul de mult cum sugerează și numele, acțiunea Mută ​​modifică pozițiile particulelor în funcție de viteza lor.
  • A invarti - Similar acțiunii Mută, acțiunea Spin actualizează unghiul de rotire a particulelor în funcție de valoarea omega a particulelor (viteza unghiulară).
  • Amortizare - Această acțiune multiplică viteza unei particule cu un factor din intervalul [0, 1], simulând efectele de amortizare și încetinind treptat particulele. Un factor de unul nu înseamnă nici o amortizare: particulele se mișcă liber ca și cum nu ar exista nici un efect de amortizare; un factor de zero înseamnă amortizare totală: toate particulele nu se pot mișca puțin. Acest factor este determinat de "coeficientul de amortizare" prin următoarea formulă: "factor = 1 - (coeficient de amortizare)". Parametrul transmis constructorului este coeficientul de amortizare; aici vrem doar un efect mic de amortizare, deci folosim valoarea 0.1 pentru coeficientul.
  • ScaleCurve - Acțiunea ScaleCurve modifică scala unei particule în funcție de valoarea sa de viață. Ea crește de la o scară inițială la o scală normală după naștere și se estompează la o scară finală pe măsură ce moare. Desigur, o particulă poate avea și o valoare inițială sau finală care este mai mare decât scala normală; depinde doar de alegerea personală. În multe cazuri, dorim ca particulele să aibă o valoare inițială și finală de zero, care este valoarea implicită. Primul parametru din constructor reprezintă timpul de creștere al particulelor, iar al doilea este timpul de fading; astfel încât să trecem în constantele GROWING_TIME și SHRINKING_TIME ca prim și, respectiv, al doilea parametru. Timpul de creștere este de 5, ceea ce înseamnă că o particulă crește de la zero la scara normală în timpul primelor 5 unități de viață; iar timpul de contracție este de 15, ceea ce înseamnă că o particulă scade la scară zero la ultimele 15 unități de viață. Rețineți că tranziția este, în mod implicit, liniară, dar poate fi utilizată orice fuzionare ușoară, în special ecuațiile de relaxare create de Robert Penner. Există o altă acțiune similară numită AlphaCurve, care funcționează pe valori alfa în același mod.

Asta e. Emitorul nostru sa terminat. Iată codul pentru acest emițător în întregime, inclusiv declarațiile de import incluse.

 pachet import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; import idv.cjcat.stardust.common.actions.ScaleCurve; import idv.cjcat.stardust.common.clocks.Clock; import idv.cjcat.stardust.common.initializers.Life; import idv.cjcat.stardust.common.initializers.Scale; import idv.cjcat.stardust.common.math.UniformRandom; import idv.cjcat.stardust.twoD.actions.Damping; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.actions.Spin; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Omega; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Rotation; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; clasa publica StarEmitter extinde Emitter2D / ** * Constante * / const static privat LIFE_AVG: Number = 30; contabil static privat LIFE_VAR: Number = 10; static static const SCALE_AVG: Number = 1; static static const SCALE_VAR: Number = 0.4; constr. statică privată GROWING_TIME: Număr = 5; constrângere statică privată SHRINKING_TIME: număr = 10; static static const SPEED_AVG: Number = 10; constrângere statică privată SPEED_VAR: Number = 8; constrângere statică privată OMEGA_AVG: Number = 0; static static const OMEGA_VAR: Number = 5; constanta statică privată DAMPING: Number = 0.1; public var punct: SinglePoint; funcție publică StarEmitter (ceas: ceas) super (ceas); punct = nou SinglePoint (); // inițializatorii addInitializer (noul DisplayObjectClass (Star)); addInitializer (noua viață (noul UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (noua scară (noul UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (noua poziție (punct)); addInitializer (noua Velocity (noua LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (noua rotație (nouă UniformRandom (0, 180))); addInitializer (noul Omega (noul UniformRandom (OMEGA_AVG, OMEGA_VAR))); // actions addAction (new Age ()); addAction (noul DeathLife ()); addAction (new Move ()); addAction (nou Spin ()); addAction (noua amortizare (DAMPING)); addAction (noua ScaleCurve (GROWING_TIME, SHRINKING_TIME)); 

Pasul 8: Finalizați clasa de documente

Acum este momentul să vă întoarceți la clasa de documente și să o terminați. Să aruncăm o privire la sarcinile rămase.

  • Creați o instanță StarEmitter - Vom exemplifica clasa StarEmitter pe care tocmai am terminat-o.
  • Atribuiți un obiect Ceas la emițător - Vrem o rată constantă de emisie de particule, așa că vom folosi clasa SteadyClock. Parametrul transmis constructorului ceasului este rata de emisie sau, cu alte cuvinte, numărul de particule noi create în fiecare etapă a emițătorului; o rată fracționată de 0,5 înseamnă în fiecare etapă a emițătorului, există o șansă de 50% pentru a crea o nouă particulă și o șansă de 50% pentru a nu crea particule.
  • Creați un Renderer - Pentru a vizualiza efectul de particule, vom avea nevoie de un redare. DisplayObjectRenderer ar trebui să fie utilizat împreună cu inițializatorul DisplayObjectClass: inițializatorul atribuie un obiect afișat fiecărei particule, iar elementul de redare adaugă aceste obiecte de afișare în lista de afișare a unui container, actualizându-le în mod constant. De asemenea, nu uitați să adăugați emițătorul la redare.
  • Sunați repetat bucla principală - Ultimul pas îl ține pe Stardust să funcționeze. Aici vom face uz de evenimentul enter-frame.
  • Mai jos este codul complet pentru clasa de documente, inclusiv declarațiile de import incluse.

 pachet import flash.display.Sprite; import flash.display.StageScaleMode; importul flash.events.Event; import flash.geom.Rectangle; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.renderers.Renderer; import idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; clasa publica StarParticles extinde Sprite private var emitter: StarEmitter; funcția publică StarParticles () // instanțiează emițătorul StarEmitter = noul StarEmitter (noul SteadyClock (0.5)); // container container sprite var: Sprite = Sprite nou (); // renderer care face efectul de particule var renderer: Renderer = new DisplayObjectRenderer (container); renderer.addEmitter (emițător); // adăugați containerul în lista de afișare, deasupra fundalului addChildAt (container, 1); // utilizați evenimentul enter-frame addEventListener (Event.ENTER_FRAME, mainLoop);  funcția privată mainLoop (e: Event): void // actualizați poziția SinglePoint la poziția mouse-ului emitter.point.x = mouseX; emitter.point.y = mouseY; // apelați buclă principală emitter.step (); 

În cele din urmă, am terminat! Acum, să aruncăm o privire asupra rezultatului. Apăsați CTRL + ENTER în Flash pentru a testa filmul și veți vedea rezultatul.


Varianta 1: Stele animate

Nu am terminat încă! Să mai facem câteva variante. Primul folosește clipuri video animate pentru particulele noastre.

Pasul 9: Creați o animație Timeline

Această primă variație este destul de simplă, fără implicarea codării suplimentare. Este la fel de simplu ca crearea unei animații de bază a cronologiei. Editați simbolul Star în Flash IDE, creați un alt cadru cheie și modificați culoarea stelei în acest cadru în roșu. Acest lucru determină, în esență, ca stelele să clipească între galben și roșu. S-ar putea să doriți să introduceți mai multe cadre goale între ele, deoarece o rată a cadrelor de 60fps este prea rapidă pentru a clipi două cadre.

Acum, testați filmul și verificați rezultatul. Efectul intermitent al stelei arată desen animat; acest lucru poate fi folosit pentru efecte clasice de amețeală, care este văzut de obicei în desene animate.


Varianta 2: Timpul de reglare dinamic

Așa cum am menționat mai devreme, una dintre trăsăturile Stardust este "scala de simulare reglabilă", ceea ce înseamnă că scala de timp folosită de Stardust pentru simularea particulelor poate fi ajustată dinamic. Totul se face schimbând proprietatea Emitter.stepTimeInterval, care este 1 în mod implicit. Următorul fragment de cod modifică această valoare la 2, rezultând particule care se mișcă de două ori mai repede, iar emițătorul creând particule noi la viteză dublă.

 emitter.stepTimeInterval = 2;

În această variantă, vom crea un cursor pe scenă și îl vom folosi pentru a regla dinamic intervalul de timp al simulării.

Pasul 10: Creați un cursor

Glisați o componentă a cursorului din panoul Componente în scenă. Denumiți "cursorul".

Pasul 11: Parametrii cursorului de configurare

Ne-ar plăcea să alunecați cursorul între 0,5 și 2, ceea ce înseamnă că dorim ca simularea noastră de particule să fie cel puțin jumătate mai rapidă decât cea normală și cel mult de două ori la fast. De asemenea, setați "liveDragging" la adevărat, pentru a putea vedea actualizarea pe măsură ce curățăm degetul mare al glisorului.

Pasul 12: Ascultarea cursorului

Acum trebuie să ascultăm schimbarea evenimentului pentru a schimba dinamic intervalul de timp al simulării. În primul rând, importați clasa SliderEvent în clasa de documente.

 import fl.events.SliderEvent;

Apoi, ascultați cursorul evenimentului de schimbare al constructorului de clase de documente.

 slider.addEventListener (SliderEvent.CHANGE, changeTimescale);

În cele din urmă, schimbați intervalul de timp al simulării în ascultător. Adăugați următorul ascultător la clasa de documente.

 schimbarea funcției privateTimescale (e: SliderEvent): void emitter.stepTimeInterval = slider.value; 

Să vedem rezultatul. Observați că, pe măsură ce îndepărtați degetul mare al glisorului spre stânga, simularea particulelor încetinește și, dacă sculați, simularea merge mai repede.


Cod