Manipulere Particle Motion med Stardust Particle Engine - Del 1

Manipulating Particle Motion med Stardust Particle Engine - Del 1
Del
Del
Del
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Stardust Particle Engine gir to viktige tilnærminger til fritt å manipulere partikkelbevegelse, nemlig gravitasjonsfelt og deflektorer. Gravitasjonsfelt er vektorfelt som påvirker en partikkel akselerasjon, og deflektorer manipulere både en partikkel posisjon og hastighet.


Den første delen av denne opplæringen dekker grunnleggende partikkelbevegelse og gravitasjonsfelt. Dessuten viser det hvordan du lage dine egne gravitasjonsfelt. Den andre delen fokuserer på deflektorer og hvordan du kan lage egne deflektorer.

Før kunnskap om grunnleggende bruk av Stardust er nødvendig for å fortsette å lese denne opplæringen. Hvis du ikke er kjent med Stardust, kan du sjekke ut min forrige tutorial om emnet, Shoot out Stars med Stardust Particle Engine, før du går videre.



Endelig resultat Forhåndsvisning

La oss ta en titt på det endelige resultatet vi skal jobbe mot. Dette er et eksempel på en tilpasset vortex gravitasjonsfelt.



Partikkel Motion Basics

Det er tid for noen raske flashback på high school fysikk. Husk grunn kinematikk? Det handler om fortrengning, som er bare en mer avansert måte å si "stilling", og dens forhold til tid. For omfanget av denne opplæringen, vi trenger bare en ganske enkel forståelse av emnet.

Displacement

Displacement betyr den aktuelle posisjonen til et objekt. I denne opplæringen de "objekter" vi er i hovedsak arbeider med er partikler i 2D plass. I 2D-plass, er forskyvningen av et objekt representert ved en 2D vektor.

Velocity

En objektets hastighet betegner hvor raskt et objekts posisjon endringer og retningen på endringen. Hastigheten av et objekt i 2D mellomrom er også representert ved en 2D-vektor. Vektoren er x- og y-komponentene representerer retning av endring av posisjon, og vektoren absolutte verdien angir objektets hastighet, altså hvor fort objektet beveger seg.

Acceleration

Akselerasjon er å hastigheten som hastigheten er til fortrengning. Akselerasjon av en gjenstand som betegner hvor fort et objekts hastighetsendringer og retningen av forandringen. Akkurat som hastigheten til et objekt i 2D plass, er et objekt akselerasjon representert ved en 2D vektor.



Vector Fields

En annen ting verdt å nevne er begrepet vektorfelt. Du kan i utgangspunktet se et vektorfelt som en funksjon som tar en vektor som sin inngang og utganger en annen vektor. Gravitasjonsfelt er en slags vektorfelt som tar stilling vektorer som innganger og utgang akselerasjon vektorer. For eksempel, i fysikk simulering, vanligvis et enhetlig gravitasjons pekende nedover er brukt på alle objekter; i dette tilfellet, er det gravitasjonsfelt som representerer gravitasjons et vektorfelt som utmater en konstant vektor (som peker nedover), uansett hva inngangsposisjonsvektorer er.

Dette er en visualisert grafisk fremstilling av et vektorfelt. Utgangen vektor av et gitt inngangsvektor (1, 2) er (0,5, 0,5), mens utgangen fra en inngang (4, 3) er (-0,5, 0,5).

The Field klasse i Dust representerer et 2D vektorfelt, og sin 3D motstykke, representerer Field3D klassen en 3D vektorfelt. I denne opplæringen, vil vi bare fokusere på 2D vektorfelt.

Field.getMotionData () metoden tar en Particle2D objekt, som inneholder en partikkel 2D posisjon og hastighet informasjon, som parameter. Denne metoden returnerer en MotionData2D objekt, en 2D-vektor "value objekt" som bestod av x- og y-komponenter. Kombinert med Gravity action, kan en Feltet objekt brukes som et gravitasjonsfelt, der produksjonen blir brukt til å manipulere partikkelhastighet.

Det er alt for vår high school fysikk oppsummering. Nå er det tid for litt skikkelig Stardust ting.



The Gravity Handling

Som tidligere nevnt, gjør Gravity handling klasse bruk av felt gjenstander som gravitasjonsfelt for å manipulere partikkelhastighet. Her er hvordan du oppretter en uniform vektorfelt, et vektorfelt som returnerer en konstant vektor uansett hva input gitt, og pakk den inn i en Gravity handling.
//Skape en enhetlig vektorfelt peker nedover (husk positive y-koordinat betyr "ned" i Flash) Var felt: Feltet = new UniformField (0, 1); //skape et tyngdepunkt actionvar Vekt: Gravity = new Gravity (); //legge til feltet til tyngdekraften actiongravity.addField (felt);

Dette Gravity handlingen er nå klar til å brukes på samme måte som alle andre vanlige Stardust handlinger
//legge alvoret handlingen til en emitteremitter.addAction (tyngdekraft);



. Eksempel: Windy Regn

Vi kommer til å lage en vind regn effekt ved hjelp av tyngdekraften handlingen



Trinn 1:. Basic Raining Effect

Opprett en ny Flash-dokument, velger du en mørk farge for bakgrunn, tegne en regndråpe på scenen, og konvertere den regndråpe til et filmklipp symbol, eksporteres for Action med en klasse navnet "Raindrop". Slett regndråpe eksempel på scenen etterpå.

Nå skal vi lage et AS filen for dokumentet klassen, og en AS-fil for regn emitter. Jeg vil ikke forklare koden her, siden jeg allerede har dekket grunnleggende bruk av Stardust i min forrige tutorial. Hvis du ikke er kjent med Stardust eller du trenger litt forfriskning, jeg anbefaler sterkt at du leser min forrige tutorial før du går videre.

Dette er dokumentet klassen.
Pakke {import flash.display. *; import flash.events. *; import idv.cjcat.stardust.common.emitters. *; import idv.cjcat.stardust.common.renderers. *; import idv.cjcat.stardust.twoD.renderers. *; public class WindyRain strekker Sprite {private Var emitter: Emitter; private Var renderer: Renderer; offentlig funksjon WindyRain () {emitter = new RainEmitter (); renderer = new DisplayObjectRenderer (denne); renderer.addEmitter (emitter); addEventListener (Event.ENTER_FRAME, mainLoop); } Private funksjon mainLoop (e: Hendelses): void {emitter.step (); }}}

Og dette er emitter klasse som brukes i dokumentet klassen
pakke {import idv.cjcat.stardust.common.clocks *..; import idv.cjcat.stardust.common.initializers. *; importere idv.cjcat.stardust.common.math. *; import idv.cjcat.stardust.twoD.actions. *; import idv.cjcat.stardust.twoD.emitters. *; import idv.cjcat.stardust.twoD.initializers. *; import idv.cjcat.stardust.twoD.zones. *; public class RainEmitter strekker Emitter2D {offentlig funksjon RainEmitter () {super (ny SteadyClock (1)); //initializers addInitializer (nye DisplayObjectClass (Raindrop)); addInitializer (ny posisjon (ny RectZone (-300, -40, 940, 20))); addInitializer (ny Velocity (ny RectZone (-0,5, 2, 1, 3))); addInitializer (ny Mass (ny UniformRandom (2, 1))); addInitializer (ny Scale (ny UniformRandom (1, 0,2))); //handlinger addAction (ny Move ()); addAction (ny Oriented (1, 180)); addAction (ny DeathZone (ny RectZone (-300, -40, 960, 480), true)); }}}

Dette er hva vår nåværende fremgang ser ut



Trinn 2: Gjør det Windy

Nå skal vi gjøre det regn effekt vind ved å legge en. uniform gravitasjonsfelt som "trekker" regndråpene til høyre. .
//Oppretter et uniformfield som returnerer alltid legge til følgende kode i konstruktør av RainEmitter klasse (0,5, 0) Var felt: Feltet = new UniformField (0,5, 0); //take partikkelmassen inn accountfield.massless = false; //skape et tyngdepunkt handling og legge til feltet til itvar Vekt: Gravity = new Gravity (); gravity.addField (felt); //legge alvoret handlingen til emitteraddAction (tyngdekraft);

Merk at vi sette Field.massless eiendom til false, som er sant som standard. Når den er satt til sann, dette fører til eiendommen felt for å opptre som vanlige gravitasjonsfelt, og rammer alle objekter likt uavhengig av massen. Men når eiendommen er satt til false, er partikkelmassen tatt i betraktning: partikler med større masse er mindre påvirket av feltet, mens partikler med mindre masse påvirkes mer. Det er derfor vi brukte Mass initializer i vår forrige emitter kode, for å legge til noen tilfeldig i regnet effekt.

Test filmen på nytt, og dette er hva vår resultatet ser ut. Raindrops er nå rammet av et gravitasjonsfelt, og alle er "trukket" til høyre



. Eksempel: Turbulens

Nå skal vi bytte UniformField objekt med en BitmapField objekt , tilbake vektorfelt basert på en bitmap rens fargekanaler, for å skape en turbulens effekt. Hvis du har jobbet med Actionscript for en stund, kan du forvente å bruke BitmapData.perlinNoise () metoden når du tenker på turbulens, og det er akkurat hva vi skal gjøre.

Her er hva en prøve Perlin støy bitmap ser ut. Perlin støy er et utmerket algoritme for å generere støy for å simulere turbulens, vann bølge, sky, etc. Du kan finne mer informasjon om Perlin støy her.

Bitmap Fields

Du kan lure på, hvis vi kommer til å bruke BitmapData.perlinNoise () metode for å generere en Perlin støy bitmap, hvordan skal vi bruke denne bitmap som en vektor felt? Vel, dette er hva den BitmapField klassen er for. Det tar en bitmap og konverterer den til et vektorfelt.

La oss si at vi har et bitmap-feltet som X kanal
er satt til rød Hotell og Y-kanal
er grønn
. Dette betyr at når banen tar et inngangsvektor, si, (2, 3), ser det opp til bitmap piksel ved (2, 3) og utgangsvektor er X-komponent bestemmes fra bildeelement røde kanalen og Y-komponenten er bestemmes ut fra den grønne kanalen. Når komponentene av en inngangsvektor ikke er heltall, blir de første avrundet.

A farge kanalens verdi i området fra 0 til 255, 127 er den gjennomsnittlige. En verdi mindre enn 127 regnes som negative av bitmap-feltet, mens en verdi større enn 127 er tatt positive. Zero er mest negative
nummer og 255 er mest positive
en. For eksempel, dersom vi har et bildeelement med en farge 0xff0000 i heksadesimal representasjonen, noe som betyr en rød kanal med verdi 255 og grønne kanal med 0, da bitmap feltets utgang for dette bildeelement vil være en vektor med X-komponenten av et mest positiv
mulig antall og Y-komponent en mest negative
mulig tall, der dette mest positive /negative mulige antall
, eller maksimalt antall
, er spesifikk for bitmap-feltet. For å være mer presis, her er formelen for pixel til vektor konvertering



Trinn 1:. Basic Flying piler

Opprett en ny Flash-dokument. Tegn en pil på scenen, konvertere det til et symbol kalt "Arrow" og eksportere den for Actionscript.

Opprett en AS-fil for dokumentet klassen. Dette er nesten det samme som i forrige eksempel
pakke {import flash.display *..; import flash.events. *; import idv.cjcat.stardust.common.emitters. *; import idv.cjcat.stardust.common.renderers. *; import idv.cjcat.stardust.twoD.renderers. *; public class Turbulens strekker Sprite {private Var emitter: Emitter; private Var renderer: Renderer; offentlig funksjon Turbulence () {emitter = new ArrowEmitter (); renderer = new DisplayObjectRenderer (denne); renderer.addEmitter (emitter); addEventListener (Event.ENTER_FRAME, mainLoop); } Private funksjon mainLoop (e: Hendelses): void {emitter.step (); }}}

Opprett en annen AS fil for vår emitter klasse
pakke {import idv.cjcat.stardust.common.actions *..; import idv.cjcat.stardust.common.clocks. *; import idv.cjcat.stardust.common.initializers. *; importere idv.cjcat.stardust.common.math. *; import idv.cjcat.stardust.twoD.actions. *; import idv.cjcat.stardust.twoD.emitters. *; import idv.cjcat.stardust.twoD.initializers. *; import idv.cjcat.stardust.twoD.zones. *; public class ArrowEmitter strekker Emitter2D {offentlig funksjon ArrowEmitter () {super (ny SteadyClock (1)); //initializers addInitializer (nye DisplayObjectClass (pil)); addInitializer (nytt liv (ny UniformRandom (50, 10))); addInitializer (ny posisjon (ny Single (320, 200))); addInitializer (ny Velocity (ny LazySectorZone (3, 2))); addInitializer (ny Mass (ny UniformRandom (2, 1))); addInitializer (ny Scale (ny UniformRandom (1, 0,2))); //handlinger addAction (New Age ()); addAction (ny DeathLife ()); addAction (ny Move ()); addAction (ny Oriented ()); addAction (ny ScaleCurve (10, 10)); }}}

Den nåværende fremgang ser slik ut



Trinn 2:. Gjør det turbulente

Legg til følgende kode som skaper en 640-by-480 Perlin støy bitmap data i emitter konstruktøren. For detaljerte forklaringer om hver parameter i BitmapData.perlinNoise () metoden, kan du se i denne dokumentasjonen. For å gjøre det enkelt, skaper følgende kode en Perlin støy bitmap med "oktaver" omtrent på størrelse 50X50, og støy består av røde og grønne fargekanalene
//oppretter et Perlin støy bitmap datavar støy. BitmapData = new BitmapData (640, 400); noise.perlinNoise (50, 50, 1, 0, true, true, 1 | 2);

Deretter oppretter du en BitmapField objekt og tilordne bitmap data til det gjennom oppdateringen () metoden . Da resten av koden om Gravity handlingen er nøyaktig det samme som i forrige eksempel
//opprette en uniformfield som alltid vender tilbake (0,5, 0) Var feltet: BitmapField = new BitmapField (); field.channelX = 1.; //sett X-kanalen til redfield.channelY = 2; //satt Y kanal til greenfield.max = 1; //sette maks vektorkomponent absolutt valuefield.update (støy); //oppdatere feltet med støy bitmap //ta partikkelmassen inn accountfield.massless = false; //skape et tyngdepunkt handling og legge til feltet til itvar Vekt: Gravity = new Gravity (); gravity.addField (felt); //legge alvoret handlingen til emitteraddAction (gravitasjon).

Nå teste filmen på nytt, og du skal se våre flygende piler nå opplever turbulens



Custom Fields

Vi har brukt UniformField og BitmapField levert av Stardust, og nå skal vi lage våre egne felt ved å utvide Feltet klasse og overstyring av getMotionData2D () -metoden.

getMotionData2D tar Particle2D parameter som inngang, som inneholder posisjonsvektorinformasjon til partikkelen, og det er inngang til feltet. Metoden returnerer en MotionData2D objekt, som representerer utgangssignalet fra feltet. Det er alt du trenger å vite for å lage et egendefinert felt. La oss lage en tilpasset vortex feltet.

Nedenfor er visualisert grafen til vår vortex feltet. Det er ganske selvforklarende hvorfor det kalles en vortex feltet.

Her er formelen for vår vortex feltet.

Og vortex feltet klassen er så enkelt som koden under. Vi har gjort bruk av Vec2D klassen til å gjøre alt det skitne arbeidet med å rotere en vektor med 90 grader med klokken og sette vektoren absolutte verdi. Deretter dumpe vi vektoren er x- og y-komponenter inn i en MotionData2D objekt, som er av den objekttypen som skal returneres
pakke {import idv.cjcat.stardust.twoD.fields *..; import idv.cjcat.stardust.twoD.geom. *; import idv.cjcat.stardust.twoD.particles. *; public class VortexField strekker Feltet {public Var centerX: Number; offentlig Var centery: Number; offentlig Var styrke: Number; offentlig funksjon VortexField (centerX: Number = 0, centery: Antall = 0, styrke: Number = 1) {this.centerX = centerX; this.centerY = Centery; this.strength = styrke; } Styre beskyttet funksjon calculateMotionData2D (partikkel: Particle2D): MotionData2D {var dx: Number = particle.x - centerX; Var dy: Number = particle.y - Centery; Var vec: Vec2D = new Vec2D (dx, dy); vec.length = styrke; vec.rotateThis (90); returnere nye MotionData2D (vec.x, vec.y); }}}

Nå som vi har vår egendefinert felt, la oss teste det ut i følgende eksempel



. Eksempel: Vortex

Dette eksemplet fungerer som en prøvetur for vår vortex vektorfeltet. Det er så enkelt som å bytte et felt med en ny. Endre følgende kode fra forrige eksempel fra denne
//oppretter et uniformfield som alltid vender tilbake (0,5, 0) Var feltet: BitmapField = new BitmapField (); field.channelX = 1; //sett X-kanalen til redfield.channelY = 2; //satt Y kanal til greenfield.max = 1; //sette maks vecotr lengthfield.update (støy); //oppdatere feltet med støy bitmap

til dette
//skape en vortex felt sentrert på (320, 200) med styrke 1Var feltet: VortexField = new VortexField (); field.centerX = 320; feltet. centery = 200; field.strength = 1;

Og vi er ferdige. Du kan teste filmen og se vortex effekt. Søt!



Konklusjon

Du har sett hvordan du bruker Gravity handling og Feltet klasse å påvirke partikkelhastighet. Og du har lært hvordan du kan lage dine egne vektorfelt som skal brukes som gravitasjonsfelt. Den neste delen av denne veiledningen vil vise deg hvordan du kan gjøre bruk av deflektorer å manipulere både partikkel posisjon og hastighet samtidig.

Tusen takk for lesing!