Skjut ut stjärnor med Stardust Particle Engine

I denna handledning presenterar jag dig för Stardust Particle Engine. Först ska jag visa dig hur du sätter upp Stardust, och sedan täcker jag de grundläggande Stardust-gruppansvaren och hur de samarbetar för att göra Stardust-arbetet i sin helhet.

Därefter kommer vi att titta på en Stardusts allmänna arbetsflöde och komma ner för att skapa en partikeleffekt med stjärnor som skjuter ut från muspekaren. stjärnorna kommer att sakta gradvis, växa större efter födseln och krympa när de dör.

Slutligen demonstrerar jag flexibiliteten hos Stardust genom att skapa flera variationer från det redan fullständiga exemplet, inklusive att använda animerade filmklipp som partiklar, variabel partikel-simuleringstidsskala och skjuta ut visningsobjekt av olika klasser från en enda emitter.

Denna handledning är avsedd för personer som redan är bekanta med ActionScript 3.0 objektorienterad programmering (OOP), så jag antar att du redan vet väldigt bra vilka klasser, objekt, arv och gränssnitt som betyder. Inget problem med OOP? Låt oss sedan skjuta några stjärnor!




Stardust partikelmotor

Som namnet antyder, används Stardust för att skapa partikeleffekter. Om du är en erfaren ActionScripter kanske du har skapat partikeleffekter från början, och säger "Jag är helt cool med att skapa partikeleffekter från början, så varför skulle jag behöva en partikelmotor i alla fall?" Jo, Stardust är här för att hjälpa dig att fokusera mer på verkliga partikelbeteenden än att oroa dig för de tråkiga underliggande lågnivåerna, till exempel minneshantering. I stället för att skriva kod för att ta hand om partikeldata, initiera och använda resurser, med Stardust, kommer du att hoppa över dessa tråkiga rutiner och bara bestämma hur du vill att dina partiklar ska uppträda.

Stardust funktioner

Klassstrukturen i Stardust inspirerades av FLiNT Particle System, en annan ActionScript 3.0 partikelmotor. De delar sålunda några liknande grundläggande funktioner.

  • 2D- och 3D-partikeleffekter - Stardust kan användas för att skapa både 2D- och 3D-partikeleffekter. Den har en egen inbyggd 3D-motor, och den kan också användas för att arbeta i kombination med andra 3D-motorer från tredje part, inklusive ZedBox, Papervision3D och ND3D.
  • Hög Extensibility - Stardust ger en stor uppsättning partikelbeteenden och renderers till ditt förfogande. Om ingen av dem passar dina behov kan du alltid utöka basklassen och skapa egna anpassade partikelbeteenden. Du kan också skapa din egen renderare för att arbeta med en annan 3D-motor som inte stöds av Stardust.

Förutom dessa grundläggande funktioner ger Stardust flera avancerade funktioner för erfarna användare.

  • Justerbar simulering Timescale - Tidsplanen som används för partikel-simulering kan justeras dynamiskt under körtiden. Om du till exempel ändrar tidsskala till hälften av originalet, kommer partikel effekten att vara halv så snabb som normal hastighet; och om du anpassar tidsskala till två gånger originalet, kommer partikel effekten att simuleras dubbelt så fort som normalt. Den här funktionen kan vara till nytta när du skapar ett spel som har långsamma effekter: partikeleffekten kan sakta ner för att matcha din spelmotorens hastighet, synkronisera med din spelanimation och grafik.
  • XML-serialisering - Du kan omvandla ditt partikelsystem till en fil i XML-format som kan lagras på din hårddisk, senare laddad under körtiden och tolkas för att rekonstruera ditt orignalpartikelsystem. Det här är mycket användbart när du arbetar med ett stort projekt. Säg att du bara vill dimensionera dina partiklar lite, så du anpassar parametrarna i källkoden och kompilerar hela din Flash-applikation, vilket kan ta en minut eller till och med över fem minuter om ditt projekt är extremt stort. Är det värt det? Absolut inte. Det är ett totalt slöseri med tid. Med hjälp av XML-serialiseringsfunktionen för att spara ditt partikelsystem i externa XML-filer separerar du parametrar från källkoden för huvudapplikationen. Så vad du behöver göra är att helt enkelt öppna XML-filen, ändra parametervärdena, spara den och öppna din huvudapplikation igen. Det är allt! Ingen omkompilering krävs alls. Jag skulle säga att detta är det perfekta sättet att arbeta med stora projekt.

När det gäller partikel effekter är det mycket viktigt att hantera massiva partikeldata effektivt. Stardust gör stor användning av objektpooler och länkade listor för att förbättra prestanda:

  • Objektpooler - Använda objekt lagras i en pool; Senare, om ett föremål av samma typ är nödvändigt, aktiverar Stardust det inte omedelbart, men kontrollerar om det finns något föremål som tidigare lagrats i objektpoolen till vänster. Om ja, tar Stardust helt enkelt det objektet och använder det istället för att skapa ett helt nytt objekt. Vanligtvis involverar partikeleffekter mycket objektinriktning, vilket är CPU-konsumtion. Genom att använda objektpooler, reducerar Stardust kraftigt instantiationkostnaden.
  • Länkade länkar - Det är väldigt lätt och frestande att lagra partikeldata i en array; I ett fall då partiklar skapas och avlägsnas mycket ofta sker emellertid mycket splicing för att ta bort döda partiklar. Array-splitsning är en processkonsumtionsk process, speciellt för långa arrays. För en länkad lista, oavsett hur länge listan är, tar det alltid lika kort tid att splittra döda partiklar. Från version 1.1 började Stardust använda länkade listor internt för att lagra partikeldata.

Ställa in Stardust

Innan vi kommer ner till den faktiska kodningen måste vi ta en kopia av Stardust Particle Engine. Det släpps ut under MIT-licens, vilket betyder att det är helt gratis, oavsett om du vill använda det i ett kommersiellt eller icke-kommersiellt projekt.

Här är Stardusts projektwebbplats: http://code.google.com/p/stardust-particle-engine/

Du kan ladda ner Stardust här: http://code.google.com/p/stardust-particle-engine/downloads/list

Vid skrivningstillfället är den senaste versionen som kan hämtas från nedladdningslistan 1.1.132 Beta. Du kan alltid fånga den senaste versionen från SVN-förvaret (vilket kanske inte är stabilt).

På projektets hemsida kan du också hitta fler tillbehör som API-dokumentation och en kopia av PDF-manualen. Det finns även videotutorials på YouTube.

Stardust Class Responsibilities

Här kommer jag kortfattat att täcka Stardust-kärnklasserna och deras ansvar.

StardustElement

Denna klass är superklassen för alla kärnklasser, som definierar egenskaper och metoder speciellt för XML-serialisering.

Slumpmässig

I allmänhet handlar partikeleffekter om att styra en mängd enheter med liknande men slumpmässigt utseende och beteende. Den slumpmässiga klassen är för att generera slumptal, som kan användas i Stardust för randomisering av partikelegenskaper. UniformRandom-klassen är till exempel en underklass i Random-klassen och namnet berättar allt: det slumptal som genereras av ett UniformRandom-objekt är jämnt fördelat, och jag kommer att använda den här klassen speciellt för hela handledningen.

Zon

Det finns tillfällen då ett ettdimensionellt slumptal inte räcker. Ibland behöver vi tvådimensionella slumptal, som i huvudsak är par av slumptal, för egenskaper som position och hastighet. Zonklassen är för att generera tvådimensionella slumptalspar. Denna klass modellerar ett slumptalspar som en slumpmässig punkt i en 2D-zon. Cirkelsonen genererar till exempel slumptalspar (x, y) från slumpmässiga punkter i en cirkulär region. Random och Zone klasserna används huvudsakligen av Initializer-klassen, som kommer att täckas senare. Zone3D-klassen är 3D-motsvarigheten till den här klassen, för 3D-partikeleffekter.

Sändare

Emitter klassen är i grunden där alla lågnivån är inkapslade. En emitter initierar nyskapade partiklar innan de läggs till i simuleringen, uppdaterar partikelegenskaper i varje huvudlocks iteration och tar bort döda partiklar från simuleringen. Metoden Emitter.step () är vad du vill åberopa flera gånger för att hålla Stardust igång.

Klocka

Klockklassen bestämmer graden av ny partikelskapande för sändare. Ett Emitterobjekt innehar exakt en referens till ett klockobjekt. I början av varje Emitter.step () metodsamtal frågar emitorn klockobjektet hur många nya partiklar den ska skapa. Ta till exempel SteadyClock-klassen, det berättar emittenter att skapa nya partiklar i en konstant takt.

initierare

Denna klass är för initiering av nyskapade partiklar. Ett Initializer-objekt måste läggas till en emitter för att det ska fungera. I grunden initialiserar ett Initializer-underklass endast en partikelegenskap. Till exempel initialiserar massinitierarklassen massan av nya partiklar. Vissa initialiserare accepterar ett slumpmässigt objekt som en konstruktorparameter för initiering av partiklar med slumpmässiga värden. Följande kod skapar en Life initializer som initierar partikelliv till värden centrerad vid 50 med variation av 10, nämligen mellan intervallet 40 till 60.

 nytt liv (nytt UniformRandom (50, 10));

Verkan

Åtgärdsobjekt uppdaterar partikelegenskaper i varje iteration av huvudslingan (Emiter.step () -metoden). Till exempel uppdaterar Action Action-klassen partikelpositioner enligt hastighet. Ett åtgärdsobjekt måste läggas till en emitter för att det ska fungera.

General Stardust Workflow

Nu när du vet hur kärnklasserna samarbetar tillsammans, låt oss ta en titt på ett generellt arbetsflöde för Stardust.

Du börjar med att skapa en emitter. Använd Emitter2D-klassen för 2D-partikeleffekter och Emitter3D-klassen för 3D-effekter.

 var emitter: Emitter = ny Emitter2D ();

För att ange graden av partikelskapande behöver vi en klocka. Detta kan antingen ställas in av egenskapen Emitter.clock eller genom att överföra en klocka som den första parametern till emittentens konstruktör.

 // property approach emitter.clock = nytt SteadyClock (1); // Constructor approach var emitter: Emitter = Ny Emitter2D (New SteadyClock (1));

Lägg till initialisatorer till emitern genom metoden Emitter.addInitializer ().

 emitter.addInitializer (New Life (New UniformRandom (50, 10))); emitter.addInitializer (new Scale (new UniformRandom (1, 0.2)));

Lägg till åtgärder i emitern genom metoden Emitter.addAction ().

 emitter.addAction (new Move ()); emitter.addAction (new Spin ());

Skapa en renderer och lägg emitteren till renderaren genom metoden Renderer.addEmitter ().

 var renderer: Renderer = ny DisplayObjectRenderer (container); // "behållare" är vår behållare sprite renderer.addEmitter (emitter);

Slutligen, ring upprepade gånger med Emitter.step () -metoden för att hålla partikel-simuleringen på gång. Du kanske vill använda enter-frame-händelsen eller en timer för att göra detta. I en enda anrop av Emitter.step () -metoden bestämmer klockan hur många nya partiklar som ska skapas, dessa nya partiklar initieras av initieringsmedel, alla partiklar uppdateras av åtgärder, döda partiklar avlägsnas och slutligen gör renderaren partikel effekten.

 // enter-frame händelse tillvägagångssätt addEventListener (Event.ENTER_FRAME, mainLoop); // timer-inställningstimer.addEventListener (TimerEvent.TIMER, mainLoop); funktion mainLoop (e: Event): void emitter.step (); 

OK. Det är ganska mycket allt för Stardust primer. Nu är det dags att öppna Flash IDE och få dina händer smutsiga.

Steg 1: Skapa ett nytt Flash-dokument

Skapa ett nytt Flash-dokument med en dimension på 640X400 en bildfrekvens på 60fps och en mörk bakgrund. Här gjorde jag en mörkblå gradientbakgrund. Förresten fungerar Stardust bra med både Flash Player 9 och 10, så det är okej, oavsett om du använder Flash CS3 eller CS4. I den här handledningen använder jag Flash CS3.

Steg 2: Rita en stjärna

Vi skapar en partikeleffekt med stjärnor, så vi måste dra en stjärna och konvertera den till en symbol, som naturligtvis exporteras till ActionScript. Denna symbol kommer att användas senare för att göra vår partikel effekt. Namn på symbolen och den exporterade klassen "Star".

Steg 3: Skapa dokumentklassen

Skapa en ny dokumentklass och namnge den StarParticles.

 paket import flash.display.Sprite; offentlig klass StarParticles utökar Sprite public function StarParticles () 

Steg 4: Förläng emitteren

Som nämnts i det allmänna arbetsflödet är det första steget att skapa en emitter. Och nästa steg är att lägga till initialisatorer och åtgärder till emitern. Även om detta kan göras i dokument klasskonstruktören rekommenderar jag starkt att det görs i en separat Emitter-underklass. Det är alltid bättre att skilja utformningen av partikelbeteendet från huvudprogrammet. Genom att göra så är koden mycket renare och lättare att ändra i framtiden utan att vara blandad med huvudprogrammet.

Vi ska skapa en 2D-partikeleffekt, så Emitter2D är emitterklassen vi kommer att utöka. Utvid Emitter2D-klassen och namnge den StarEmitter, eftersom vi ska göra det skjuta ut stjärnor senare. Emitterkonstruktören accepterar en klockparameter, så vi kommer att deklarera en konstruktorparameter för att vidarebefordra en klockobjektreferens till superklassens konstruktör.

 paket import idv.cjcat.stardust.twoD.emitters.Emitter2D; offentlig klass StarEmitter utökar Emitter2D offentlig funktion StarEmitter (klocka: Klocka) // överför klockobjektet till superklassens konstruktör super (klocka); 

Steg 5: Förklara konstanter

Ett bättre tillvägagångssätt att skapa en emitter-underklass är att deklarera partikelparametrar som statiska konstanter, grupperade på en enda plats. Så om du vill tweak parametrarna vet du alltid var du ska hitta deklarationerna. Betydelsen av dessa konstanter kommer att förklaras senare när de används.

 // genomsnittlig livslängd privat statisk konst LIFE_AVG: Number = 30; // livslängdsvarig privat statisk const LIFE_VAR: Number = 10; // genomsnittlig skala privat statisk konst SCALE_AVG: Number = 1; // skala variation privat statisk konst SCALE_VAR: Number = 0.4; // skala odlingstid privat statisk const GROWING_TIME: Number = 5; // skala krympningstid privat statisk const SHRINKING_TIME: Number = 10; // medelhastighet privat statisk const SPEED_AVG: Number = 10; // hastighetsvariationen privat statisk const SPEED_VAR: Number = 8; // genomsnittlig omega (vinkelhastighet) privat statisk konst OMEGA_AVG: Number = 0; // omega variant privat statisk konst OMEGA_VAR: Number = 5; // dämpningskoefficient privat statisk konst DAMPING: Number = 0.1;

Steg 6: Lägga till initialiserare

Vilka initialiserare behöver vi skapa vår partikel effekt? Låt oss ta en titt på listan nedan:

  • DisplayObjectClass - Denna initialiserare tilldelar ett visst visningsobjekt till varje partikel, som kommer att användas av en DisplayObjectRenderer för att göra partikel effekter. Konstruktören accepterar en klassreferens till den visningsobjektklass vi vill inställa för denna handledning kommer denna klass att vara Star klassen (symbolen) som vi skapade i steg 2.
  • Liv - Denna initialiserare tilldelar varje partikel ett slumpmässigt livsvärde. Senare lägger vi till åtgärder för emitteren för att tömma detta livsvärde genom tiden, och att markera en partikel som död om dess livsvärde når noll. Ett slumpmässigt objekt överförs till konstruktören, som kommer att användas av denna initialiserare för att generera slumpmässigt värde för partiklarnas liv. I de flesta fall är UniformRandom-klassen bekväm och tillräcklig; Den första parametern för UniformRandom-konstruktören är mittvärdet (eller medelvärdet) av de slumptal som genereras och den andra är radie (eller variation). Ett UniformRandom-objekt med centrum 20 och variation 5 genererar till exempel slumptal inom området [15, 25]. Här använder vi LIFE_AVG-konstanten för mittvärdet och LIFE_VAR för radien.
  • Skala - Liksom livsinitieraren initierar scale-initialiseraren en partikelskala till ett slumpmässigt värde, bestämt av ett slumpmässigt objekt som överförs till initieringsens konstruktion. Här använder vi SCALE_AVG-konstanten för mittvärdet och SCALE_VAR för radie.
  • Placera - Denna initialiserare tilldelar en partikel en slumpmässig position. Till skillnad från Life and Scale initialiserare, som endast behöver 1D slumptal, kräver positioninställningsenheten 2D slumptalspargeneratorer. Som beskrivs i avsnittet Stardust Class Responsibilities är zonklassen exakt för detta ändamål. Zonobjektet som skickas till initialiserarens konstruktor används för att generera 2D slumptalspar, som kommer att tilldelas partiklar som positionsvektorer. I denna handledning kommer vi att göra stjärnor skjuta ut från en enda punkt som ligger på muspekaren, så vi använder en SinglePoint-klass, som är en zonunderklass. För att dynamiskt kunna justera koordinatet för detta SinglePoint-objekt från dokumentklassen, måste vi avslöja en referens till det här objektobjektet via en offentlig egendom. Det här är vad "punkt" -egenskapen är för.
  • Hastighet - Samma som positionsinitieraren behöver hastighetsinitieraren ett zonobjekt för att generera 2D slumpmässiga värdespar för att initiera partikelhastigheter. En 2D-vektor som genereras av zonobjektet, som är koordinaten för en slumpmässig punkt i zonen, tilldelas partiklar som deras hastigheter. Här använder vi LazySectorZone-klassen som representerar en sektorsregion. En sektor är en del av en cirkel som är innesluten av två radier och två vinklar. För LazySectorZone är de två vinklarna som standard 0 och 360, vilket representerar en hel vinkel runt en cirkel. Den första konstruktörsparametern i LazySectorZone-klassen är medelvärdet av de två radierna och den andra är variationen av radierna. I det här fallet representerar medelvärdet av de två radierna medelhastigheten, och variationen av radier representerar variation av hastighet. Här använder vi SPEED_AVG-konstanten för den första parametern och SPEED_VAR för den andra.
  • Rotation - Rotationsinitieraren initierar en partikelns rotationsvinkel till ett slumpmässigt värde. Och som några av de ovannämnda initialiserare accepterar konstruktören ett slumpmässigt objekt för att generera ett slumpmässigt värde. Eftersom vi skulle vilja ha partiklar med vinklar från 0 till 360 grader, använder vi 0 som centrum och 180 som radien för UniformRandom objektet.
  • Omega - Omega, som i de flesta fysikhandböcker, betyder vinkelhastighet. Med detta sagt är syftet med denna initialiserare klart: det initierar en partikelns vinkelhastighet till ett slumpmässigt värde, och OMEGA_AVG-konstanten används som centrum och OMEGA_VAR som radien för UniformRandom-objektet.

Och här är koden:

 punkt = ny SinglePoint (); addInitializer (new DisplayObjectClass (Star)); addInitializer (nytt liv (nytt UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (new Scale (new UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (ny position (punkt)); addInitializer (new Velocity (new LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (new Rotation (new UniformRandom (0, 180))); addInitializer (new Omega (new UniformRandom (OMEGA_AVG, OMEGA_VAR)));

Steg 7: Lägga till åtgärder

Okej, vi är klara med initialisatorerna. Nu är det dags att lägga till åtgärder till emitern. Nedan finns en lista över åtgärder vi behöver:

  • Ålder - Åldersverkan minskar partikelns livsvärde med 1 i varje emittersteg.
  • DeathLife - När en partikelns livsvärde når noll, markerar den här åtgärden partikeln som död, och ändrar dess isDead-egenskap från falsk till sann. Vid slutet av ett emittersteg avlägsnas döda partiklar.
  • Flytta - Ganska mycket som namnet antyder, uppdaterar Move-åtgärden partikelpositioner enligt deras hastigheter.
  • Snurra - På samma sätt som Move-åtgärden uppdaterar Spin-åtgärden en partikelns rotationsvinkel i enlighet med partikelns omega-värde (vinkelhastighet).
  • dämpning - Denna åtgärd multiplicerar en partikelns vellyd med en faktor inom intervallet [0, 1], simulerar dämpningseffekter och gradvis saktar ner partikeln. En faktor av en betyder ingen dämpning alls: partiklar rör sig fritt som om det inte fanns någon dämpande effekt; en faktor noll betyder total dämpning: alla partiklar kan inte flytta lite. Denna faktor bestäms av "dämpningskoefficienten" genom denna formel: "faktor = 1 - (dämpningskoefficient)". Parametern som passerar till konstruktorn är dämpningskoefficienten; här vill vi bara ha en liten dämpningseffekt, så vi använder värdet 0,1 för koefficienten.
  • ScaleCurve - ScaleCurve-åtgärden ändrar en partikelskala enligt dess livsvärde. Den växer från en initial skala till normal skala efter födseln och bleknar till en slutlig skala när den dör. Naturligtvis kan en partikel också ha ett initialt eller slutligt skalvärde som är större än den normala skalan; det beror bara på personligt val. I många fall vill vi att partiklar har ett initialt och slutligt skalvärde på noll, vilket är standardvärdet. Den första parametern i konstruktorn står för en partikels växartid, och den andra är blekningstiden; så vi övergår i GROWING_TIME och SHRINKING_TIME konstanterna som respektive respektive respektive parameter. Växtiden är 5, vilket betyder att en partikel växer från nollskala till normal skala under sin första 5 livscykel. och krympningstiden är 15, vilket innebär att en partikel krymper till nollskala vid den sista 15 livstiden. Observera att övergången är linjär som standard, men alla lättnader kan användas, särskilt de lättnader som skapats av Robert Penner. Det finns en annan liknande åtgärd som heter AlphaCurve, som fungerar på alfa-värden på samma sätt.

Det är allt. Vår emitter är klar. Här är koden för den här emitteren i dess helhet, nödvändiga importmeddelanden inkluderade.

 paket import idv.cjcat.stardust.common.actions.Age; importera idv.cjcat.stardust.common.actions.DeathLife; importera idv.cjcat.stardust.common.actions.ScaleCurve; importera idv.cjcat.stardust.common.clocks.Clock; importera idv.cjcat.stardust.common.initializers.Life; importera idv.cjcat.stardust.common.initializers.Scale; importera idv.cjcat.stardust.common.math.UniformRandom; importera idv.cjcat.stardust.twoD.actions.Damping; importera idv.cjcat.stardust.twoD.actions.Move; importera idv.cjcat.stardust.twoD.actions.Spin; importera idv.cjcat.stardust.twoD.emitters.Emitter2D; importera idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importera idv.cjcat.stardust.twoD.initializers.Omega; importera idv.cjcat.stardust.twoD.initializers.Position; importera idv.cjcat.stardust.twoD.initializers.Rotation; importera idv.cjcat.stardust.twoD.initializers.Velocity; importera idv.cjcat.stardust.twoD.zones.LazySectorZone; importera idv.cjcat.stardust.twoD.zones.SinglePoint; offentlig klass StarEmitter utökar Emitter2D / ** * Konstanter * / privat statisk const LIFE_AVG: Number = 30; privat statisk const LIFE_VAR: Number = 10; privat statisk konst SCALE_AVG: Number = 1; privat statisk konst SCALE_VAR: Number = 0.4; privat statisk const GROWING_TIME: Number = 5; privat statisk konst SHRINKING_TIME: Number = 10; privat statisk const SPEED_AVG: Number = 10; privat statisk const SPEED_VAR: Number = 8; privat statisk konst OMEGA_AVG: Number = 0; privat statisk konst OMEGA_VAR: Number = 5; privat statisk konst DAMPING: Number = 0.1; allmän var punkt: SinglePoint; offentlig funktion StarEmitter (klocka: Klocka) super (klocka); punkt = ny SinglePoint (); // initialisatorer addInitializer (new DisplayObjectClass (Star)); addInitializer (nytt liv (nytt UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (new Scale (new UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (ny position (punkt)); addInitializer (new Velocity (new LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (new Rotation (new UniformRandom (0, 180))); addInitializer (new Omega (new UniformRandom (OMEGA_AVG, OMEGA_VAR))); // åtgärder addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (new Spin ()); addAction (new Damping (DAMPING)); addAction (ny ScaleCurve (GROWING_TIME, SHRINKING_TIME)); 

Steg 8: Avsluta dokumentklassen

Nu är det dags att gå tillbaka till dokumentklassen och avsluta det. Låt oss ta en titt på de återstående uppgifterna.

  • Skapa en StarEmitter-förekomst - Vi kommer att instansera StarEmitter-klassen som vi just avslutat.
  • Tilldela ett klockobjekt till emitern - Vi vill ha en stadig partikelutsläpp, så vi använder SteadyClock-klassen. Parametern som passerar till klockans konstruktor är utsläppshastigheten, eller med andra ord antalet nya partiklar som skapats i varje emittersteg; en fraktionerad hastighet av 0,5 medel i varje emittersteg finns det 50% chans att en ny partikel skapas och 50% risk för ingen partikel skapad.
  • Skapa en Renderer - För att visualisera partikel effekten, kommer vi att behöva en renderer. DisplayObjectRenderer ska användas tillsammans med DisplayObjectClass-initieraren: initieraren tilldelar ett visningsobjekt till varje partikel och renderaren lägger till dessa visningsobjekt i en behållares visningslista, och uppdaterar dem kontinuerligt. Glöm inte att lägga emitteren till renderaren.
  • Ring upp huvudbandet igen - Detta sista steg håller Stardust igång. Här kommer vi att använda sig av inramningsevenemanget.
  • Nedan finns den fullständiga koden för dokumentklassen, nödvändiga importmeddelanden inkluderade.

 paket import flash.display.Sprite; importera flash.display.StageScaleMode; importera flash.events.Event; importera flash.geom.Rectangle; importera idv.cjcat.stardust.common.clocks.SteadyClock; importera idv.cjcat.stardust.common.renderers.Renderer; importera idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; offentlig klass StarParticles utökar Sprite private var emitter: StarEmitter; offentlig funktion StarParticles () // instantiate StarEmitter emitter = ny StarEmitter (new SteadyClock (0.5)); // behållarens sprite var container: Sprite = new Sprite (); // den renderare som gör partikel effekten var renderer: Renderer = ny DisplayObjectRenderer (container); renderer.addEmitter (emitter); // lägg till behållaren till visningslistan ovanför bakgrunden addChildAt (behållare, 1); // utnyttja enter-frame händelsen addEventListener (Event.ENTER_FRAME, mainLoop);  privat funktion mainLoop (e: Event): void // uppdatera SinglePoint-positionen till muspositionen emitter.point.x = mouseX; emitter.point.y = mouseY; // ring huvudlösen emitter.step (); 

Slutligen är vi färdiga! Låt oss nu titta på resultatet. Tryck CTRL + ENTER i Flash för att testa filmen, så ser du resultatet.


Variation 1: Animerade stjärnor

Vi är inte färdiga ännu! Låt oss göra några fler variationer. Den första använder animerade filmklipp till våra partiklar.

Steg 9: Skapa en tidslinjeanimering

Denna första variationen är ganska enkel, utan att någon extra kodning ingår. Det är lika enkelt som att skapa en grundläggande tidslinjeanimation. Redigera stjärnasymbolen i Flash IDE, skapa en annan nyckelram och ändra stjärnans färg i den här ramen till röd. Detta orsakar i huvudsak stjärnorna att blinka mellan gult och rött. Du kanske vill infoga några fler tomma ramar mellan, eftersom en bildhastighet på 60 bilder per sekund är för snabb för att två-ramar blinkar.

Testa nu filmen och kolla resultatet. Den blinkande stjärn-effekten ser skönhet ut; Detta kan användas för klassiska svimma-stjärniga effekter, vilket vanligtvis ses i tecknade film.


Variation 2: Justera tidsskalan dynamiskt

Som jag nämnde tidigare är en av Stardust-funktionen "justerbar simuleringstidskala", vilket innebär att tidsskala som används av Stardust för partikel-simulering kan justeras dynamiskt. Allt görs genom att ändra egenskapen Emitter.stepTimeInterval, som är 1 som standard. Följande kodbitning ändrar detta värde till 2, vilket resulterar i att partiklar rör sig två gånger så fort och emitterar skapar nya partiklar med dubbel hastighet.

 emitter.stepTimeInterval = 2;

I denna variation skapar vi en skjutreglage på scenen och använder den för att dynamiskt justera simuleringstiden.

Steg 10: Skapa en Slider

Dra en Slider-komponent ut från komponentpanelen till scenen. Namnge det "slider".

Steg 11: Parametrar för inställningsreglage

Vi skulle vilja ha skjutreglaget mellan 0,5 och 2, vilket innebär att vi vill att vår partikel simulering ska vara minst hälften så snabb som normalt och högst två gånger snabbt. Ställ också "liveDragging" på sant så vi kan se uppdateringen när vi skrubbar skjutreglaget tummen.

Steg 12: Slider Event Listener

Nu måste vi lyssna på reglaget ändringshändelse för att dynamiskt ändra simuleringstiden. Först importera du SliderEvent-klassen i dokumentklassen.

 importera fl.events.SliderEvent;

Och lyssna sedan på reglaget ändringshändelse i dokumentkonstruktionen.

 slider.addEventListener (SliderEvent.CHANGE, changeTimescale);

Ändra ändå simuleringstiden i lyssnaren. Lägg till följande lyssnare i dokumentklassen.

 privat funktion förändringTimeskala (e: SliderEvent): void emitter.stepTimeInterval = slider.value; 

Låt oss titta på resultatet. Observera att när du skrubbar reglaget tummen åt vänster, sänker partikel-simuleringen, och om du skrubbar höger går simuleringen snabbare.


Variation 3: Flera visningsklasser

Stardust tillhandahåller en speciell initialiserare som heter SwitchInitializer. Konstruktören accepterar två arrays som parametrar; den första är en uppsättning initialisatorer, och den andra, med samma längd som den första, är en uppsättning av "vikter". Varje gång Stardust använder denna initialiserare för att initiera partiklar, väljs en av initialisatorerna i den första matrisen slumpmässigt för att initiera partiklarna. Ju mer vikt en initialiserare har desto mer sannolikt kommer den att plockas för initialisering. I den här variationen kommer vi att göra emitern skjuta ut inte bara stjärnor utan även vita cirklar.

Steg 13: Rita en cirkel

Rita en vit cirkel, konvertera den till en symbol, exporteras för ActionScript, och namnge symbolen och klassen "Circle". Det här är den klass vi ska använda för de vita cirklarna.

Steg 14: Skapa switchinitialiseraren

Öppna StarEmitter-klassen och radera den följande raden. Detta inaktiverar DisplayObjectClass-initieraren som vi ställde in i tidigare steg.

 addInitializer (new DisplayObjectClass (Star));

Lägg nu följande kod till konstruktören. Vi skulle vilja ha stjärnor och cirklar som ska emitteras lika troligt, så vi ger dem båda en vikt på 1.

 // initialiseraren för stjärnor var doc1: DisplayObjectClass = ny DisplayObjectClass (Star); // initialiseraren för vita cirklar var doc2: DisplayObjectClass = ny DisplayObjectClass (Circle); // switchinitialiseraren var: SwitchInitializer = ny SwitchInitializer ([doc1, doc2], [1, 1]); // lägg till omkopplarinitieraren till emitern addInitiali