Aceasta este a doua parte a acestui tutorial. Vă voi arăta cum să manipulați mișcarea particulelor cu deflectori.
Este necesară cunoașterea prealabilă a elementelor de bază ale mișcării și a câmpurilor vectoriale. Vă recomandăm să completați prima parte a acestui tutorial înainte de a vă deplasa.
Aruncati o privire la rezultatul final la care vom lucra. Este un exemplu al unui efect de pardoseală, cu particule care coboară de pe podea.
Destul de mult ca câmpurile de gravitație, un deflector ia datele de mișcare ale particulelor ca intrări. Apoi, deflectorul suprascrie mișcarea particulei cu ieșirea sa, numai că ieșirea conține acum date de viteză în plus față de datele de poziție. Astfel, în spațiul 2D, ieșirea unui deflector este un vector 4D; primele două componente ale vectorului 4D reprezintă componentele x și y ale vectorului de poziție (denotate X și y), iar ultimele două componente reprezintă componentele x și y ale vectorului de viteză (notat vx și vy).
Amintiți-vă Camp
clasa și Gravitatie
acțiune din prima parte a acestui tutorial? Procedura este similară. Tu creezi deflectorul
obiecte care manipulează mișcările de particule și apoi le adăugați la Devia
acțiune, la fel cum ați adăuga Camp
obiecte la Gravitatie
acțiune. Acum, să ne uităm la un exemplu rapid.
În acest exemplu, vom folosi LineDeflector
clasa pentru a crea un efect de particule-bouncing-off-floor. Un deflector de linie simulează în esență o linie infinit de lungă în spațiul 2D, cu o parte fiind spațiu deschis, iar cealaltă parte solidă; particulele sunt permise numai în spațiul deschis și nu sunt permise în spațiul solid. Atunci când particulele provin din partea spațiului deschis, lovind linia, ei vor sări înapoi. Particle.collisionRadius
proprietatea, reprezentând raza unei particule, este luată în considerare.
Deflectorul de linie utilizează un vector normal și un punct în care linia trece prin spațiul 2D pentru a determina linia. Iată o ilustrație care vă oferă o idee mai bună.
Creați un nou document Flash, trageți un cerc cu o rază de 10 și transformați-l într-un simbol, exportat pentru ActionScript cu un nume de clasă Cerc
.
Creați un fișier AS pentru clasa de documente. Clasa creează un emițător și un renderer. Dacă aveți nevoie de o reîmprospătare a utilizării de bază a Stardust, puteți consulta acest tutorial.
pachet import flash.display.Sprite; importul flash.events.Event; import idv.cjcat.stardust.common.emitters.Emitter; import idv.cjcat.stardust.common.renderers.Renderer; import idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; clasa publica FloorEffect extinde Sprite private var emitter: Emitter; privat var renderer: Renderer; funcția publică FloorEffect () emitter = new CircleEmitter (); renderer = nou DisplayObjectRenderer (acest lucru); renderer.addEmitter (emițător); addEventListener (Event.ENTER_FRAME, mainLoop); funcția privată mainLoop (e: Event): void emitter.step ();
Clasa emițătorului este prezentată mai jos. În mod normal, împușcă particule de cerc și particulele sunt afectate de un câmp de gravitație uniform, îndreptat în jos.
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.SteadyClock; 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.Gravity; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.fields.Field; import idv.cjcat.stardust.twoD.fields.UniformField; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; clasa publică CircleEmitter extinde Emitter2D funcția publică CircleEmitter () super (noul SteadyClock (1)); // inițializatorii addInitializer (noul DisplayObjectClass (Circle)); addInitializer (viata noua (noul UniformRandom (60, 10))); addInitializer (noua poziție (noul SinglePoint (320, 100))); addInitializer (noua Velocitate (noua LazySectorZone (8, 4))); addInitializer (noua scară (noul UniformRandom (1, 0.4))); addInitializer (noul CollisionRadius (10)); // actions addAction (new Age ()); addAction (noul DeathLife ()); addAction (new Move ()); addAction (noua ScaleCurve (0, 10)); câmpul gravitational var: câmp = nou UniformField (0, 0,5); Var gravitate: gravitatea = noua gravitate (); gravity.addField (câmp); addAction (gravitate);
Acum ați creat un efect cu particule care se împușcă din centrul scenei, fiind tras în jos de gravitație. Asa arata:
Milestone Vizualizați-l online Adăugați codul următor în constructorul emițătorului. Creează un deflector de linie, îl adaugă la deflectorul
acțiune, apoi adaugă acțiunea la emițător, activând astfel efectul deflectorului. Primele două parametri constructori pentru LineDeflector
clasa este coordonatul unui punct pe linie, iar ultimii doi parametri sunt componentele x și y ale vectorului normal al liniei. Deflector.bounce
proprietatea determină "bounciness" liniei, 1 provocând revenire completă, iar 0 nu înseamnă nici o revenire.
// crea un deflector de linie care trece prin punctul (320, 320) și deflectorul normal (0, -1): Deflector = nou LineDeflector (320, 320, 0, -1); deflector.bounce = 0,6; var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); addAction (devia);
Puteți, de asemenea, să desenați o reprezentare vizuală a liniei pe scenă pentru a avea o imagine mai bună.
Bine, am terminat cu acest exemplu. Acum, să aruncăm o privire asupra rezultatului nostru final.
Milestone Vizualizați-l online În acest exemplu, vom folosi Casetă de încadrare
deflector pentru a constrânge particulele într-o zonă dreptunghiulară.
Clasa de documente rămâne aceeași ca și exemplul anterior, dar vom schimba clasa emițătorului. Aceasta este clasa emițător de bază a acestui exemplu. În comparație cu clasa emițător din exemplul precedent, SteadClock
este schimbat în a ImpulseClock
pentru a crea instantaneu 20 de particule la început, zona de poziție este schimbată dintr-un singur punct într-o zonă dreptunghiulară care se potrivește cu dimensiunea scenei, Viteză
inițializatorul este încetinit puțin, Viaţă
inițializatorul este eliminat deoarece dorim ca particulele să rămână permanent pe scenă Vârstă
și DeathLife
acțiunile nu sunt, la rândul lor, necesare și eliminate, și ScaleCurve
este, de asemenea, eliminat. Unele importuri sunt, de asemenea, adăugate și eliminate; puteți să copiați codul de mai jos pentru comoditate.
pachet import idv.cjcat.stardust.common.clocks.ImpulseClock; import idv.cjcat.stardust.common.initializers.CollisionRadius; import idv.cjcat.stardust.common.initializers.Scale; import idv.cjcat.stardust.common.math.UniformRandom; import idv.cjcat.stardust.twoD.actions.Deflect; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.deflectors.BoundingBox; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.RectZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; clasa publică CircleEmitter extinde Emitter2D private var impulseClock: ImpulseClock; funcția publică CircleEmitter () super (impulseClock = nou ImpulseClock (20)); impulseClock.impulse (); // inițializatorii addInitializer (noul DisplayObjectClass (Circle)); addInitializer (noua poziție (noua RectZone (0, 0, 640, 400))); addInitializer (noua Velocity (noua LazySectorZone (3, 2))); addInitializer (noua scară (noul UniformRandom (1, 0.4))); addInitializer (noul CollisionRadius (10)); // acțiuni addAction (new Move ());
Destul de mult ca în exemplul anterior, adăugăm acum codul următor în constructorul emițătorului pentru a utiliza Devia
acțiune, doar că de data aceasta vom folosi Casetă de încadrare
deflectorul pentru a constrânge particulele într-o regiune dreptunghiulară care se potrivește cu dimensiunea scenei.
// deflector var deflector: Deflector = nou BoundingBox (0, 0, 640, 400); var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); addAction (devia);
Asta e. Nimic nu se schimbă și acum avem constrânse particule într-o cutie de legătură. Testați filmul și veți vedea rezultatul.
Milestone Vizualizați-l online Acum, vom crea deflectori personalizați pe cont propriu. Să înțelegem prima dată deflectorul
clasa pe care o vom prelungi.
deflectorul
clasa este baza pentru toate deflectorii. Pentru a crea deflectori personalizați, ar trebui să extindeți această clasă și să suprascrieți calculateMotionData4D ()
și apoi returnați a MotionData4D
obiect reprezentând ieșirea vectorului 4D a deflectorului. Contribuția la dispoziția dumneavoastră, la fel ca și Camp
clasa, este inclus în Particle2D
obiect trecut în metoda ca parametru. Puteți folosi acest lucru Particle2D
obiect pentru a determina ieșirea dvs. Apropo, dacă această metodă returnează a nul
valoare, Devia
acțiunea ar presupune că nu doriți să modificați mișcarea curentă a particulelor, să ignorați particula și apoi să continuați să procesați următoarea particulă.
De exemplu, următorul deflector ar roti vectorul de viteză al fiecărei particule cu un grad în ceas.
pachet import idv.cjcat.stardust.twoD.geom.Vec2D; import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; clasa publica Rotator extinde Deflector suprascriere functie protejata calculateMotionData4D (particula: Particle2D): MotionData4D var viteza: Vec2D = Vec2D noi (particle.vx, particle.vy); velocity.rotateThis (1); returnează MotionData4D (particle.x, particle.y, viteza.x, viteza.y);
În acest exemplu, vom extinde deflectorul
clasa și de a crea propriul nostru deflector, simularea unui tub, care este, în esență, două deflectori de linie sandwiching un spațiu liber în formă de tub.
Copiați documentul Flash împreună cu Cerc
simbolul și documentul din primul exemplu. Aici vom crea o altă clasă de emițători, încă numită CircleEmitter
. De această dată emițătorul emite particule din centrul treptei și nu se aplică un câmp de gravitație.
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.SteadyClock; import idv.cjcat.stardust.common.initializers.CollisionRadius; 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.Deflect; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; clasa publică CircleEmitter extinde Emitter2D funcția publică CircleEmitter () super (noul SteadyClock (1)); // inițializatorii addInitializer (noul DisplayObjectClass (Circle)); addInitializer (viata noua (noul UniformRandom (60, 10))); addInitializer (poziție nouă (noul SinglePoint (320, 200))); / / center stage addInitializer (noua Velocity (noua LazySectorZone (8, 4))); addInitializer (noua scară (noul UniformRandom (1, 0.4))); addInitializer (noul CollisionRadius (10)); // actions addAction (new Age ()); addAction (noul DeathLife ()); addAction (new Move ()); addAction (noua ScaleCurve (0, 10));
Acum vom crea clasa deflectoarelor cu tuburi. Detaliile sunt explicate în comentarii.
pachet import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; clasa publică TubeDeflector extinde Deflector private var y1: Number; privat var y2: Număr; funcția publică TubeDeflector (y1: Număr, y2: Număr) // y2 ar trebui să fie mai mare decât y2 dacă (y1> y2) // swap y1 și y2 dacă y1 este mai mare var temp: Number = y1; y1 = y2; y2 = temp; this.y1 = y1; acest y2 = y2; suprascrie funcția protejată calculateMotionData4D (particulă: Particle2D): MotionData4D // componentele de ieșire, inițializate la datele originale ale particulei de mișcare var x: Number = particle.x; var y: Numărul = particle.y; var vx: Număr = particle.vx; var vy: Numărul = particle.vy; // calculează raza de coliziune efectivă var rază: Number = particle.collisionRadius * particle.scale; // semnalizează dacă deflectorul intră în vigoare var deflected: Boolean = false; dacă (particle.y < (y1 + radius)) //particle y-coordinate is less than lower limit //set proper new y-coordinate y = y1 + radius; //set flag deflected = true; else if (particle.y > (y2 - radius)) // coordonata y a particulei este mai mare decât limita superioară // se stabilește noua coordonată y y = y2 - raza; // set flag flagged = true; dacă (deflectat) returnează noua MotionData4D (x, y, vx, vy); altceva // ignora particula și nu își actualizează datele de mișcare returnează null;
Ar trebui să știți ce vom face acum foarte bine până acum. Așa e, vom adăuga deflectorul la a Devia
acțiune și apoi adăugați acțiunea la emițător. Adăugați următorul cod în constructorul emițătorului.
// creați un deflector de tub var deflector: Deflector = nou TubeDeflector (100, 300); var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); addAction (devia);
Acum puteți testa filmul. Din nou, puteți trage și o reprezentare vizuală a deflectorului pe scenă pentru o privire mai bună.
Milestone Vizualizați-l online Acesta este sfârșitul întregului tutorial. În prima parte ați învățat despre câmpurile gravitaționale. În cea de-a doua parte, ați învățat conceptul deflectorilor și utilizarea efectivă a acestora Devia
acțiune. De asemenea, ați învățat cum să extindeți deflectorul
pentru a crea deflectori personalizați. Acum puteți să efectuați o manipulare avansată a mișcării particulelor în Stardust.
Vă mulțumesc foarte mult pentru lectură!