Manipulerer partikkelbevegelse med Stardust Particle Engine - Del 2

Dette er den andre delen av denne opplæringen. Jeg skal vise deg hvordan du kan manipulere partikkelbevegelse med deflektorer.

Forkunnskap om bevegelseskunnskap og vektorfelt er nødvendig. Jeg anbefaler på det sterkeste at du fullfører første del av denne opplæringen før du fortsetter.


Endelig resultatforhåndsvisning

Ta en titt på det endelige resultatet vi skal jobbe for. Det er et eksempel på en gulv effekt, med partikler som hopper av gulvet.


deflektorer

Like mye som tyngdekraftsfelt, tar en deflektor en partikkelens nåværende bevegelsesdata som input. Etterpå overskriver deflektoren partikkels bevegelse med sin utgang, bare at utgangen nå inneholder hastighetsdata i tillegg til stillingsdata. I 2D-rom er en deflektorens utgang således en 4D-vektor; De to første komponentene i 4D-vektoren representerer x- og y-komponenten i posisjonsvektoren (betegnet x og y), og de to siste komponentene representerer x- og y-komponenten av hastighetsvektoren (betegnet vx og vy).


Slik bruker Deflectors

Husk Felt klasse og Tyngde handling fra første del av denne opplæringen? Vel, prosedyren er lik. Du lager deflektor objekter som manipulerer partikkelbevegelser, og legg dem til avlede handling, akkurat som du vil legge til Felt gjenstander til Tyngde handling. La oss se på et raskt eksempel.


Gulv effekt

I dette eksemplet skal vi bruke LineDeflector klasse for å skape en partikkel-hoppende-off-gulv effekt. En line deflector simulerer i hovedsak en uendelig lang linje i 2D-rom, med den ene siden åpen plass og den andre siden solid; partikler er bare tillatt å være i det åpne rommet og ikke tillatt i det faste rommet. Når partikler kommer fra den åpne romsiden, og slår på linjen, vil de sprette tilbake. De Particle.collisionRadius eiendom, som representerer radius av en partikkel, tas i betraktning.

Linjedeklektor bruker en normal vektor og et punkt linjen passerer gjennom i 2D mellomrom for å bestemme linjen. Her er en illustrasjon for å gi deg en bedre ide.


Trinn 1: Gulvverkets sirkelsymbol

Opprett et nytt Flash-dokument, tegne en sirkel med radius på 10, og konverter deretter den til et symbol, eksportert for ActionScript med et klassenavn Sirkel.


Trinn 2: Gulvvirkning Dokumentklassen

Opprett en AS-fil for dokumentklassen. Klassen skaper en emitter og en renderer. Hvis du føler at du trenger en oppdatering på Stardusts grunnleggende bruk, kan du sjekke ut denne opplæringen.

 pakke import flash.display.Sprite; importere flash.events.Event; importer idv.cjcat.stardust.common.emitters.Emitter; importer idv.cjcat.stardust.common.renderers.Renderer; importer idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; offentlig klasse FloorEffect utvider Sprite private varemitter: Emitter; privat var renderer: Renderer; offentlig funksjon FloorEffect () emitter = new CircleEmitter (); renderer = ny DisplayObjectRenderer (dette); renderer.addEmitter (emitter); addEventListener (Event.ENTER_FRAME, mainLoop);  privat funksjon mainLoop (e: Event): void emitter.step (); 

Emitterklassen er vist nedenfor. Det skyter i utgangspunktet ut sirkelpartikler og partiklene påvirkes av et ensartet tyngdefelt, og peker nedover.

 pakke import idv.cjcat.stardust.common.actions.Age; importer idv.cjcat.stardust.common.actions.DeathLife; importer idv.cjcat.stardust.common.actions.ScaleCurve; importer idv.cjcat.stardust.common.clocks.SteadyClock; importer idv.cjcat.stardust.common.initializers.Life; importer idv.cjcat.stardust.common.initializers.Scale; importer idv.cjcat.stardust.common.math.UniformRandom; importere idv.cjcat.stardust.twoD.actions.Gravity; importer idv.cjcat.stardust.twoD.actions.Move; importer idv.cjcat.stardust.twoD.emitters.Emitter2D; importer idv.cjcat.stardust.twoD.fields.Field; importer idv.cjcat.stardust.twoD.fields.UniformField; importer idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Velocity; importer idv.cjcat.stardust.twoD.zones.LazySectorZone; importer idv.cjcat.stardust.twoD.zones.SinglePoint; offentlig klasse CircleEmitter strekker Emitter2D offentlig funksjon CircleEmitter () super (new SteadyClock (1)); // initialiserer addInitializer (ny DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (ny posisjon (nytt SinglePoint (320, 100))); addInitializer (new Velocity (new LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // handlinger addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (ny ScaleCurve (0, 10)); // gravity var-feltet: Felt = nytt UniformField (0, 0,5); var tyngdekraften: Gravity = new Gravity (); gravity.addField (felt); addAction (tyngdekraft); 

Nå har du skapt en effekt med partikler som skyter ut fra midten av scenen, blir trukket ned av tyngdekraften. Slik ser det ut:

Milestone Se det på nettet

Trinn 3: Gulv Effekt Legg til Deflector

Legg til folloingskoden i emitterkonstruktøren. Det skaper en linje deflector, legger den til deflektor handling, og legger til handlingen til emitteren, og dermed aktiverer deflektor effekten. De to første konstruktørparameterene for LineDeflector klassen er koordinatet til et punkt på linjen, og de to siste parameterne er x- og y-komponentene i linjens normale vektor. De Deflector.bounce eiendom bestemmer "bounciness" av linjen, 1 forårsaker fullstendig rebound, og 0 betyr ingen rebound i det hele tatt.

 // lage en linje deflektor som går gjennom punktet (320, 320) og normal (0, -1) var deflektor: Deflector = ny LineDeflector (320, 320, 0, -1); deflector.bounce = 0,6; var deflektere: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction etter (bøyes);

Du kan også tegne en visuell representasjon av linjen på scenen for å få et bedre utseende.

OK, vi er ferdige med dette eksemplet. La oss nå se på vårt endelige utfall.

Milestone Se det på nettet

Bounding Box

I dette eksemplet skal vi bruke BoundingBox deflektor for å begrense partikler i et rektangulært område.


Trinn 1: Binding Box Emitter Class

Dokumentklassen forblir den samme som forrige eksempel, men vi skal endre emitterklassen. Dette er basemittersklassen i dette eksemplet. Sammenlignet med emitterklassen i det forrige eksempelet, SteadClock blir endret til a ImpulseClock For å opprette 20 partikler i begynnelsen, blir posisjonssonen endret fra et enkelt punkt til en rektangulær sone som stemmer overens med scenestørrelsen, den Hastighet initialisereren er redusert litt, den Liv Initialiser er fjernet fordi vi vil at partikler skal være permanent på scenen, Alder og DeathLife handlinger er i sin tur ikke nødvendig og fjernet, og ScaleCurve er også fjernet. Enkel import blir også lagt til og fjernet; Du kan bare kopiere koden under for enkelhets skyld.

 pakke import idv.cjcat.stardust.common.clocks.ImpulseClock; importer idv.cjcat.stardust.common.initializers.CollisionRadius; importer idv.cjcat.stardust.common.initializers.Scale; importer idv.cjcat.stardust.common.math.UniformRandom; importer idv.cjcat.stardust.twoD.actions.Deflect; importer idv.cjcat.stardust.twoD.actions.Move; importer idv.cjcat.stardust.twoD.deflectors.BoundingBox; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.emitters.Emitter2D; importer idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Velocity; importer idv.cjcat.stardust.twoD.zones.LazySectorZone; importer idv.cjcat.stardust.twoD.zones.RectZone; importer idv.cjcat.stardust.twoD.zones.SinglePoint; offentlig klasse CircleEmitter strekker Emitter2D private var impulseClock: ImpulseClock; offentlig funksjon CircleEmitter () super (impulseClock = ny ImpulseClock (20)); impulseClock.impulse (); // initialiserer addInitializer (ny DisplayObjectClass (Circle)); addInitializer (ny posisjon (ny RectZone (0, 0, 640, 400))); addInitializer (new Velocity (new LazySectorZone (3, 2))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // handlinger addAction (new Move ()); 

Trinn 2: Bounding Box Legg til Deflector

Nesten som i forrige eksempel, legger vi nå følgende kode i emitterkonstruktøren for å bruke avlede handling, bare at denne gangen bruker vi BoundingBox deflektor for å begrense partikler i en rektangulær region som matcher scenestørrelsen.

 / deflektor var deflector: Deflector = ny BoundingBox (0, 0, 640, 400); var deflektere: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction etter (bøyes);

Trinn 3: Bounding Box Test filmen

Det er det. Ingenting mye er forandret, og nå har vi begrenset partikler i en avgrensingsboks. Test filmen, og du skal se resultatet.

Milestone Se det på nettet

Custom Deflectors

Nå skal vi skape tilpassede deflectorer på egen hånd. La oss først forstå deflektor klasse vi skal utvide.

De deflektor klassen er grunnklassen for alle deflektorer. For å skape tilpassede deflektorer, bør du utvide denne klassen og tilsidesette calculateMotionData4D () metode, og returner deretter a MotionData4D objekt som representerer 4D-vektorutgangen til deflektoren. Inngangen til din disposisjon, akkurat som Felt klassen, er inkludert i Particle2D objektet gikk inn i metoden som parameter. Du kan bruke dette Particle2D objekt for å bestemme utdataene dine. Forresten, hvis denne metoden returnerer a null verdi, den avlede handling ville anta at du ikke vil endre den aktuelle partikkels bevegelse, ignorere partikkelen, og deretter fortsette å behandle neste partikkel.

For eksempel ville følgende deflektor rotere hver partikkelhastighetsvektor med en grad klokvis.

 pakke import idv.cjcat.stardust.twoD.geom.Vec2D; importer idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.geom.MotionData4D; offentlig klasse Rotator strekker Deflector overstyr beskyttet funksjon calculateMotionData4D (partikkel: Particle2D): MotionData4D varhastighet: Vec2D = ny Vec2D (particle.vx, particle.vy); velocity.rotateThis (1); returner ny MotionData4D (partikkel.x, partikkel.y, hastighet.x, hastighet.y); 

Tube Deflector Effect

I dette eksemplet skal vi forlenge deflektor klassen og skape vår egen deflektor, simulerer et rør, som i hovedsak er to linjedivere som smelter i en rørformet ledig plass.


Trinn 1: Tube Deflector Effect Emitter Class

Kopier Flash-dokumentet, sammen med Sirkel symbolet og dokumentet fra det første eksemplet. Her skal vi lage en annen emitterklasse, fortsatt navngitt CircleEmitter. Denne gangen sender emitteren partikler fra sentrum av scenen, og ingen tyngdekraftsfelt påføres.

 pakke import idv.cjcat.stardust.common.actions.Age; importer idv.cjcat.stardust.common.actions.DeathLife; importer idv.cjcat.stardust.common.actions.ScaleCurve; importer idv.cjcat.stardust.common.clocks.SteadyClock; importer idv.cjcat.stardust.common.initializers.CollisionRadius; importer idv.cjcat.stardust.common.initializers.Life; importer idv.cjcat.stardust.common.initializers.Scale; importer idv.cjcat.stardust.common.math.UniformRandom; importer idv.cjcat.stardust.twoD.actions.Deflect; importer idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.emitters.Emitter2D; importer idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Velocity; importer idv.cjcat.stardust.twoD.zones.LazySectorZone; importer idv.cjcat.stardust.twoD.zones.SinglePoint; offentlig klasse CircleEmitter strekker Emitter2D offentlig funksjon CircleEmitter () super (new SteadyClock (1)); // initialiserer addInitializer (ny DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (ny posisjon (nytt SinglePoint (320, 200))); // scene center addInitializer (ny hastighet (ny LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // handlinger addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (ny ScaleCurve (0, 10)); 

Trinn 2: Tube Deflector Effekt Tube Deflector

Nå skal vi lage vår tube deflector klasse. Detaljer er forklart i kommentarer.

 pakke import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.geom.MotionData4D; offentlig klasse TubeDeflector strekker Deflector private var y1: Number; privat var y2: tall; offentlig funksjon TubeDeflector (y1: tall, y2: tall) // y2 skal være større enn y2 hvis (y1> y2) // bytt y1 og y2 hvis y1 er større var temp: Tall = y1; y1 = y2; y2 = temp;  this.y1 = y1; this.y2 = y2;  overstyr beskyttet funksjon calculateMotionData4D (partikkel: Particle2D): MotionData4D // utgangskomponenter, initialisert til partikkelens originale bevegelsesdata var x: Number = particle.x; var y: tall = partikkel.y; var vx: tall = partikkel.vx; var vy: Number = particle.vy; // caluculate faktisk collsion radius var radius: Number = particle.collisionRadius * particle.scale; // flagg for om deflektoren trer i kraft deflektert: Boolsk = false; hvis (partikkel.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)) // partikkel y-koordinat er større enn øvre grense // sett riktig ny y-koordinat y = y2-radius; // sett flaggbøyde = true;  hvis (avbøyet) returner ny MotionData4D (x, y, vx, vy);  ellers // ignorere partikkelen og ikke oppdatere bevegelsesdata-retur null; 

Trinn 3: Tube Deflector Effect Legg til Deflector

Du bør vite hva vi skal gjøre nå, veldig godt nå. Det er riktig, vi skal legge til deflektoren til en avlede handling og legg deretter til handlingen til emitteren. Legg til følgende kode i emitterkonstruktøren.

 // lage en rørdeflektor var deflektor: Deflector = ny TubeDeflector (100, 300); var deflektere: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction etter (bøyes);

Trinn 4: Tube Deflector Effect Test filmen

Du kan nå teste filmen. Igjen kan du også trekke litt visuell representasjon av deflektor på scenen for et bedre utseende.

Milestone Se det på nettet

Konklusjon

Dette er slutten av hele opplæringen. I første del har du lært om gravitasjonsfelt. I den andre delen har du lært begrepet deflectors og den faktiske bruken av avlede handling. Du har også lært hvordan du utvider deflektor klasse for å skape tilpassede deflectors. Nå kan du utføre avansert partikkelbevegelsesmanipulering i Stardust.

Tusen takk for lesing!