Skyt ut stjerner med Stardust Particle Engine

I denne opplæringen vil jeg introdusere Stardust Particle Engine. Først skal jeg vise deg hvordan du konfigurerer Stardust, og så skal jeg dekke de grunnleggende Stardust-klassens ansvar og hvordan de samarbeider for å få Stardust til å fungere som en helhet.

Deretter skal vi se på en Stardust generell arbeidsflyt og komme ned for å skape en partikkel-effekt med stjerner som skyter ut fra musemarkøren; stjernene vil sakte gradvis, vokse større etter fødselen, og krympe når de dør.

Til slutt vil jeg demonstrere fleksibiliteten til Stardust ved å skape flere variasjoner fra det allerede komplette eksemplet, inkludert bruk av animerte filmklipp som partikler, variabel partikkel simulering tidsskala og skyting av visningsobjekter av forskjellige klasser fra en enkelt emitter.

Denne veiledningen er ment for folk som allerede er kjent med ActionScript 3.0 objektorientert programmering (OOP), så jeg antar at du allerede vet veldig godt hvilke klasser, objekter, arv og grensesnitt som betyr. Ikke noe problem med OOP? Så la oss skyte noen stjerner!




Stardust Particle Engine

Som navnet antyder, er Stardust brukt til å skape partikkeleffekter. Hvis du er en erfaren ActionScripter, kan du ha opprettet partikkeleffekter fra grunnen mange ganger, og si "Jeg er helt kul med å skape partikkeleffekter fra grunnen av, så hvorfor ville jeg trenge en partikkelmotor uansett?" Vel, Stardust er her for å hjelpe deg med å fokusere mer på selve partikkeladferddsdesign enn å bekymre deg for de kjedelige underliggende lavnivået, for eksempel minnehåndtering. I stedet for å skrive kode for å ta vare på partikkeldata, initialisere og disponere ressurser, med Stardust, kommer du til å hoppe over disse kjedelige rutinene og bare bestemme hvordan du vil at partiklene skal oppføre deg.

Stardust funksjoner

Klassestrukturen til Stardust ble inspirert av FLiNT Particle System, en annen ActionScript 3.0 partikkelmotor. Dermed deler de noen lignende grunnleggende funksjoner.

  • 2D- og 3D-partikkeleffekter - Stardust kan brukes til å lage både 2D- og 3D-partikkeleffekter. Den har sin egen innebygde 3D-motor, og den kan også brukes til å fungere i kombinasjon med andre tredimensjonale 3D-motorer, inkludert ZedBox, Papervision3D og ND3D.
  • Høy utvidbarhet - Stardust gir et stort sett med partikkeladferd og renderere til din disposisjon. Hvis ingen av dem passer dine behov, kan du alltid utvide basisklassene og lage dine egne tilpassede partikkeladferd. Du kan også lage din egen renderer til å jobbe med en annen 3D-motor som ikke støttes av Stardust.

I tillegg til disse grunnleggende funksjonene tilbyr Stardust flere avanserte funksjoner for erfarne brukere.

  • Justerbar Simulering Timescale - Tidsskalaen som brukes til partikkelsimulering, kan dynamisk justeres i løpet av kjøretiden. For eksempel, hvis du endrer tidsskala til halvparten av originalen, vil partikkel-effekten være halv så rask som normal hastighet; og hvis du tilpasser tidsskala til to ganger originalen, vil partikkel-effekten bli simulert to ganger så fort som normalt. Denne funksjonen kan komme til nytte når du lager et spill som har sakte bevegelseseffekter: partikkel-effekten kan sakte for å matche spillmotorens hastighet, synkronisere med spillanimasjon og grafikk.
  • XML serialisering - Du kan forvandle partikkelsystemet til en fil i XML-format som kan lagres på harddisken, senere lastet i løpet av kjøretiden og tolket for å rekonstruere ditt orignale partikkelsystem. Dette er veldig nyttig når du jobber med et stort prosjekt. Si at du bare vil størrelsen på partiklene litt, slik at du justerer parametrene i kildekoden og kompilerer hele Flash-programmet, noe som kan ta et minutt eller enda over fem minutter hvis prosjektet ditt er ekstremt stort. Er det verdt det? Absolutt ikke. Det er en total bortkastet tid. Ved hjelp av XML-serialiseringsfunksjonen for å lagre partikkelsystemet i eksterne XML-filer, adskiller du parametere fra kildekoden for hovedapplikasjonen. Så hva du må gjøre er å bare åpne XML-filen, endre parameterverdiene, lagre den og åpne hovedapplikasjonen. Det er det! Ingen omkompilering er nødvendig i det hele tatt. Jeg vil si at dette er den ideelle måten å jobbe med store prosjekter.

Når det gjelder partikkeleffekter, er det svært viktig å håndtere massive partikkeldata effektivt. Stardust gjør stor bruk av objektbassenger og tilknyttede lister for å forbedre ytelsen:

  • Objektpuljer - Brukte gjenstander lagres i et basseng; senere, hvis et objekt av samme type kreves, starter Stardust ikke umiddelbart det, men kontrollerer om det er noe objekt som tidligere er lagret i objektbassenget til venstre. Hvis ja, tar Stardust ut det objektet og bruker det, i stedet for å skape et helt nytt objekt. Vanligvis involverer partikkeleffekter mye objektimplementering, som er CPU-forbruker. Ved å bruke objektbassenger, reduserer Stardust kraftig overheadkostnaden.
  • Lenkede lister - Det er veldig enkelt og fristende å lagre partikkeldata i en matrise; Imidlertid, i et tilfelle når partikler opprettes og fjernes veldig ofte, skjer det mye spalting for å fjerne døde partikler. Array splicing er en CPU-forbruker prosess, spesielt for lange arrays. For en koblet liste, uansett hvor lenge listen er, tar det alltid den samme korte tiden å skille ut døde partikler. Fra versjon 1.1 begynte Stardust å bruke koblede lister internt for å lagre partikkeldata.

Sette opp Stardust

Før vi går ned til selve kodingen, må vi ta en kopi av Stardust Particle Engine. Den er utgitt under MIT-lisens, noe som betyr at den er helt gratis, uansett om du vil bruke den i et kommersielt eller ikke-kommersielt prosjekt.

Her er Stardusts prosjektside: http://code.google.com/p/stardust-particle-engine/

Du kan laste ned Stardust her: http://code.google.com/p/stardust-particle-engine/downloads/list

Når du skriver, kan den nyeste versjonen som lastes ned fra nedlastingslisten, være 1.1.132 Beta. Du kan alltid ta tak i den siste revisjonen fra SVN-depotet (som kanskje ikke er stabilt).

På prosjektets hjemmeside kan du også finne flere tilbehør som API-dokumentasjon og en kopi av PDF-håndboken. Det er enda videoopplæringer på YouTube.

Stardust Class Responsibilities

Her skal jeg kortfattet dekke Stardust-kjerneklassene og deres ansvar.

StardustElement

Denne klassen er superklassen til alle kjerneklasser, som definerer egenskaper og metoder spesielt for XML-serialisering.

Tilfeldig

Vanligvis handler partikkelvirkninger om å kontrollere en mengde enheter med lignende, men randomisert utseende og atferd. Den tilfeldige klassen er for å generere tilfeldige tall, som kan brukes i Stardust for randomisering av partikkelegenskaper. For eksempel er UniformRandom-klassen en underklasse av Random-klassen, og navnet heter alt: det tilfeldige tallet som genereres av et UniformRandom-objekt, er jevnt fordelt, og jeg vil bruke denne klassen spesielt for hele opplæringen.

sone

Det er tider når et endimensjonalt tilfeldig tall ikke er nok. Noen ganger trenger vi todimensjonale tilfeldige tall, som egentlig er par av tilfeldige tall, for egenskaper som posisjon og hastighet. Sone-klassen er for å generere todimensjonale tilfeldige nummerpar. Denne klassen modellerer et tilfeldig talepar som et tilfeldig punkt i en 2D-sone. For eksempel genererer CircleZone tilfeldige nummerpar (x, y) fra tilfeldige punkter i en sirkulær region. Random og Zone klassene brukes hovedsakelig av Initializer-klassen, som dekkes senere. Zone3D-klassen er 3D-motparten av denne klassen, for 3D-partikkeleffekter.

emitter

Emitter klassen er i utgangspunktet hvor alle lavt nivå ting er innkapslet. En emitter initierer nyopprettede partikler før de legges til i simuleringen, oppdaterer partikkelegenskaper i hver hovedløkke iterasjon, og fjerner døde partikler fra simuleringen. Metoden Emitter.step () er hva du vil gjenta flere ganger for å holde Stardust oppe og i gang.

Klokke

Klokke-klassen bestemmer hastigheten på ny partikkelsett for emittere. Én emitterobjekt inneholder nøyaktig en referanse til et klokkeobjekt. Ved begynnelsen av hvert Emitter.step () metodeanrop spør emitteren klokkeobjektet hvor mange nye partikler den skal skape. Ta for eksempel SteadyClock-klassen, det forteller emittere å lage nye partikler med en konstant hastighet.

initializer

Denne klassen er for å initialisere nyopprettede partikler. Et Initializer-objekt må legges til en emitter for at den skal fungere. I utgangspunktet initialiserer en Initializer-underklasse bare en partikkelegenskap. For eksempel initierer Mass initialiserer klassen massen av nye partikler. Enkelte initiativer aksepterer et tilfeldig objekt som en konstruktørparameter for initialisering av partikler med randomiserte verdier. Følgende kode oppretter en Life initializer som initierer partikkel liv til verdier sentrert til 50 med variasjon på 10, nemlig mellom området 40 til 60.

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

Handling

Handlingsobjekter oppdaterer partikkelegenskaper i hver iterasjon av hovedløkken (Emiter.step () -metoden). For eksempel oppdaterer Move-handlingsklassen partikkelposisjoner i henhold til hastighet. Et handlingsobjekt må legges til en emitter for at den skal fungere.

Generell Stardust Workflow

Nå som du vet hvordan kjerneklassene samarbeider sammen, la oss se på en generell arbeidsflyt for Stardust.

Du starter med å lage en emitter. Bruk Emitter2D-klassen til 2D-partikkeleffekter og Emitter3D-klassen for 3D-effekter.

 varemitter: Emitter = ny Emitter2D ();

For å spesifisere graden av partikkeloppretting trenger vi en klokke. Dette kan enten settes av Emitter.clock-egenskapen eller ved å sende en klokke som den første parameteren til emitterens konstruktør.

 // egenskapstilgang emitter.clock = ny SteadyClock (1); // constructor approach var emitter: Emitter = ny Emitter2D (ny SteadyClock (1));

Legg til initiatorer til emitteren gjennom Emitter.addInitializer () -metoden.

 emitter.addInitializer (nytt liv (nytt UniformRandom (50, 10))); emitter.addInitializer (new Scale (new UniformRandom (1, 0.2)));

Legg til handlinger i emitteren gjennom Emitter.addAction () -metoden.

 emitter.addAction (ny Flytt ()); emitter.addAction (ny spin ());

Opprett en gjengivelse og legg emitteren til rendereren gjennom metoden Renderer.addEmitter ().

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

Til slutt, ring gjentatte ganger Emitter.step () metoden for å holde partikkel simuleringen gå. Du vil kanskje bruke enter-frame-hendelsen eller en timer for å gjøre dette. I en enkelt anrop av Emitter.step () -metoden bestemmer klokken hvor mange nye partikler som skal opprettes, disse nye partiklene initialiseres av initiatorer, alle partikler oppdateres av handlinger, døde partikler fjernes, og til slutt gjør rendereren partikkel-effekten.

 // enter-frame-tilnærming tilnærming addEventListener (Event.ENTER_FRAME, mainLoop); // timer tilnærming timer.addEventListener (TimerEvent.TIMER, mainLoop); funksjon mainLoop (e: Event): void emitter.step (); 

Ok. Det er stort sett alt for Stardust primer. Nå er det på tide å åpne Flash IDE og få hendene skitne.

Trinn 1: Opprett et nytt Flash-dokument

Opprett et nytt Flash-dokument med en dimensjon på 640X400, en rammefrekvens på 60 fps, og en mørk bakgrunn. Her laget jeg en mørkblå gradientbakgrunn. Forresten fungerer Stardust godt med både Flash Player 9 og 10, så det er greit uansett om du bruker Flash CS3 eller CS4. I denne opplæringen bruker jeg Flash CS3.

Trinn 2: Tegn en stjerne

Vi lager en partikkel-effekt med stjerner, så vi må tegne en stjerne og konvertere den til et symbol, eksportert for ActionScript selvfølgelig. Dette symbolet vil bli brukt senere for å gjengi partikkel-effekten. Navn symbolet og den eksporterte klassen "Star".

Trinn 3: Opprett dokumentklassen

Opprett en ny dokumentklasse, og navnet den StarParticles.

 pakke import flash.display.Sprite; offentlig klasse StarParticles utvider Sprite offentlig funksjon StarParticles () 

Trinn 4: Forleng emitteren

Som nevnt i den generelle arbeidsflyten, er det første trinnet å skape en emitter. Og neste trinn er å legge til initiatorer og handlinger til emitteren. Selv om dette kan gjøres i dokumentklassekonstruktøren, anbefaler jeg sterkt at det gjøres i en egen Emitter-underklasse. Det er alltid bedre å skille partikkeladferdelsesdesignet til hovedprogrammet; ved å gjøre det, koden er mye renere og enklere å endre i fremtiden, uten å være blandet opp med hovedprogrammet.

Vi skal lage en 2D partikkel effekt, så Emitter2D er emitter klassen vi skal utvide. Utvid Emitter2D-klassen og navnet den StarEmitter, siden vi skal gjøre det skyte ut stjerner senere. Emitterkonstruenten aksepterer en klokkeparameter, så vi vil erklære en konstruktorparameter for å overføre en klokkeobjektreferanse til superklassens konstruktør.

 pakke import idv.cjcat.stardust.twoD.emitters.Emitter2D; offentlig klasse StarEmitter utvider Emitter2D offentlig funksjon StarEmitter (klokke: Klokke) // pass på klokkeobjektet til superklassens superstruktør (klokke); 

Trinn 5: Erklær konstanter

En bedre tilnærming til å lage en emitter-underklasse er å erklære partikkelparametere som statiske konstanter, gruppert på et enkelt sted. Så hvis du vil tilpasse parametrene, vil du alltid vite hvor du skal finne deklarasjonene. Betydningen av disse konstantene vil bli forklart senere når de brukes.

 // gjennomsnittlig levetid privat statisk const LIFE_AVG: Number = 30; // levetid variasjon privat statisk const LIFE_VAR: Number = 10; // gjennomsnittlig skala privat statisk const SCALE_AVG: Number = 1; // skala variasjon privat statisk const SCALE_VAR: Number = 0.4; // skala dyrkingstid privat statisk const GROWING_TIME: Number = 5; // skala krympetid privat statisk const SHRINKING_TIME: Number = 10; // gjennomsnittlig hastighet privat statisk const SPEED_AVG: Number = 10; // hastighetsvariasjon privat statisk const SPEED_VAR: Number = 8; // gjennomsnittlig omega (vinkelhastighet) privat statisk const OMEGA_AVG: Number = 0; // omega variasjon privat statisk const OMEGA_VAR: Number = 5; // dempingskoeffisient privat statisk const DAMPING: Nummer = 0,1;

Trinn 6: Legge til initiativer

Hvilke initiatorer trenger vi for å skape vår partikkel effekt? La oss se på listen nedenfor:

  • DisplayObjectClass - Denne initialisereren tilordner et spesifisert visningsobjekt til hver partikkel, som vil bli brukt av en DisplayObjectRenderer til å gjengi partikkeleffekter. Konstruktøren aksepterer en klassereferanse til skjermobjektklassen vi ønsker å instansere; For denne opplæringen vil denne klassen være Star-klassen (symbolet) vi opprettet i trinn 2.
  • Liv - Denne initialiseringen tilordner hver partikkel en tilfeldig livsverdi. Senere legger vi til handlinger for emitteren for å tømme denne livsverdien over tid, og å markere en partikkel som død hvis livsverdien når null. En tilfeldig gjenstand sendes til konstruktøren, som vil bli brukt av denne initialisatoren til å generere tilfeldig verdi for partikkelens liv. I de fleste tilfeller er UniformRandom-klassen praktisk og tilstrekkelig; Den første parameteren til UniformRandom-konstruktøren er senterets (eller gjennomsnittlig) verdien av de tilfeldige tallene som genereres, og den andre er radiusen (eller varianten). For eksempel genererer et UniformRandom objekt med senter 20 og variasjon 5 tilfeldige tall innenfor [15, 25] området. Her bruker vi LIFE_AVG-konstanten for senterverdien og LIFE_VAR for radius.
  • Scale - I likhet med Life initialiserer initialiserer Skala initialiserer en partikkels skala til en tilfeldig verdi, bestemt av en tilfeldig gjenstand som sendes til initialiseringskonstruktøren. Her bruker vi SCALE_AVG-konstanten for senterverdien og SCALE_VAR for radiusen.
  • Stilling - Denne initialiseringen tildeler en partikkel en tilfeldig posisjon. I motsetning til Life and Scale-initiativtakerne, som bare trenger 1D tilfeldige tall, krever posisjonsinitiatoren 2D tilfeldige nummerpargeneratorer. Som beskrevet i avsnittet Stardust Class Responsibilities er soneklassen akkurat for dette formålet. Soneobjektet som sendes til initisatorens konstruktor, brukes til å generere 2D tilfeldige nummerpar, som vil bli tildelt partikler som posisjonvektorer. I denne opplæringen skal vi få stjernene til å skyte ut fra et enkelt punkt som befinner seg ved musemarkøren, så vi bruker en SinglePoint-klasse, som er en Sone-underklasse. For å dynamisk justere koordinatet til dette SinglePoint-objektet fra dokumentklassen, må vi avsløre en referanse til dette punktobjektet gjennom en offentlig eiendom. Dette er hva "poeng" -egenskapen er for.
  • Hastighet - Samme som posisjonsinitiator, har Velocity initialisereren en Sone-objekt for å generere 2D tilfeldig verdi par for å initialisere partikkelhastigheter. En 2D-vektor generert av sonobjektet, som er koordinatet til et tilfeldig punkt i sonen, tilordnes partikler som deres hastigheter. Her bruker vi LazySectorZone-klassen som representerer en sektorregion. En sektor er en del av en sirkel som er innelukket av to radier og to vinkler. For LazySectorZone er de to vinklene 0 og 360 som standard, og representerer en full vinkel rundt en sirkel. Den første konstruktørparameteren i LazySectorZone-klassen er gjennomsnittet av de to radiene, og det andre er variasjonen av radien. I dette tilfellet representerer gjennomsnittet av de to radiene gjennomsnittshastigheten, og variasjonen av radier representerer variasjon av hastighet. Her bruker vi SPEED_AVG-konstanten for den første parameteren og SPEED_VAR for den andre.
  • rotasjon - Rotasjonsinitialiseringen initierer en partikkelens rotasjonsvinkel til en tilfeldig verdi. Og som noen av de nevnte initiatorene, godtar konstruktøren et tilfeldig objekt for å generere en tilfeldig verdi. Siden vi vil ha partikler med vinkler som varierer fra 0 til 360 grader, bruker vi 0 som sentrum og 180 som radien til UniformRandom-objektet.
  • Omega - Omega, som i de fleste fysikk lærebøker, betyr vinkelhastighet. Med det sagt er formålet med denne initialisatoren klart: det initialiserer en partikkelens vinkelhastighet til en tilfeldig verdi, og OMEGA_AVG-konstanten brukes som sentrum og OMEGA_VAR som radius for UniformRandom-objektet.

Og her er koden:

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

Trinn 7: Legge til handlinger

Ok, vi er ferdige med initiativtakerne. Nå er det på tide å legge til handlinger til emitteren. Nedenfor er en liste over handlinger vi trenger:

  • Alder - Aldersvirkningen reduserer partikkelens livsverdi med 1 i hvert emitterstrinn.
  • DeathLife - Når en partikkels livsverdi når null, markerer denne handlingen partikkelen som død, og endrer sin isDead-egenskap fra falsk til sann. På slutten av et emittertrinn fjernes døde partikler.
  • Bevege seg - Ganske mye som navnet antyder, oppdaterer Move-handlingen partikkelposisjonene i henhold til deres hastigheter.
  • Snurre rundt - I likhet med Move-handlingen oppdaterer Spin-handlingen en partikkelens rotasjonsvinkel i henhold til partikkelens omega-verdi (vinkelhastighet).
  • damping - Denne handlingen multipliserer partikkelens vellykkede med en faktor innenfor området [0, 1], simulerer dempende effekter og gradvis senking av partikkelen. En faktor av en betyr ingen demping i det hele tatt: partikler beveger seg fritt som om det ikke var noen dempende effekt; en faktor på null betyr total demping: alle partikler kan ikke bevege seg litt. Denne faktoren bestemmes av "dempningskoeffisienten" gjennom denne formelen: "faktor = 1 - (dempingskoeffisient)". Parameteren som overføres til konstruktøren er dempningskoeffisienten; her vil vi bare ha en liten dempende effekt, så vi bruker verdien 0,1 for koeffisienten.
  • ScaleCurve - ScaleCurve-handlingen endrer partikkels skala i henhold til livsverdi. Den vokser fra en innledende skala til normal skala etter fødselen, og fades til en endelig skala mens den dør. Selvfølgelig kan en partikkel også ha en start- eller sluttskalaverdi som er større enn normal skalaen; det avhenger bare av personlig valg. I mange tilfeller ønsker vi at partikler har en innledende og endelige skalaverdi på null, som er standardverdien. Den første parameteren i konstruktøren står for en partikkels voksetid, og den andre er fadingtiden; så vi passerer i henholdsvis GROWING_TIME og SHRINKING_TIME konstantene som henholdsvis den første og den andre parameteren. Voksetiden er 5, noe som betyr at en partikkel vokser fra null skala til normal skala i løpet av de første 5 enhetene av levetiden; og krympetiden er 15, noe som betyr at en partikkel krymper til null skala ved siste 15 levetid. Merk at overgangen er lineær som standard, men noen lettelsefucntion kan brukes, spesielt de lette likningene som er opprettet av Robert Penner. Det er en annen lignende handling som heter AlphaCurve, som fungerer på alfa verdier på samme måte.

Det er det. Vår emitter er ferdig. Her er koden for denne emitteren i sin helhet, nødvendige importopplysninger inkludert.

 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.Clock; 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.Damping; importer idv.cjcat.stardust.twoD.actions.Move; importer idv.cjcat.stardust.twoD.actions.Spin; importer idv.cjcat.stardust.twoD.emitters.Emitter2D; importer idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importer idv.cjcat.stardust.twoD.initializers.Omega; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Rotation; importer idv.cjcat.stardust.twoD.initializers.Velocity; importer idv.cjcat.stardust.twoD.zones.LazySectorZone; importer idv.cjcat.stardust.twoD.zones.SinglePoint; offentlig klasse StarEmitter strekker Emitter2D / ** * Konstanter * / privat statisk const LIFE_AVG: Number = 30; privat statisk const LIFE_VAR: Number = 10; privat statisk const SCALE_AVG: Number = 1; privat statisk konst SCALE_VAR: Nummer = 0,4; privat statisk const GROWING_TIME: Number = 5; privat statisk const SHRINKING_TIME: Nummer = 10; privat statisk const SPEED_AVG: Number = 10; privat statisk const SPEED_VAR: Number = 8; privat statisk const OMEGA_AVG: Number = 0; privat statisk const OMEGA_VAR: Number = 5; privat statisk const DAMPING: Number = 0.1; offentlig var punkt: SinglePoint; offentlig funksjon StarEmitter (klokke: Klokke) super (klokke); pek = nytt SinglePoint (); // initializers addInitializer (ny DisplayObjectClass (Star)); addInitializer (new Life (new UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (new Scale (new UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (ny posisjon (punkt)); addInitializer (new Velocity (new LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (new Rotation (new UniformRandom (0, 180))); addInitializer (ny Omega (new UniformRandom (OMEGA_AVG, OMEGA_VAR))); // handlinger addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (ny spin ()); addAction (ny Damping (DAMPING)); addAction (ny ScaleCurve (GROWING_TIME, SHRINKING_TIME)); 

Trinn 8: Fullfør dokumentklassen

Nå er det på tide å gå tilbake til dokumentklassen og fullføre den. La oss ta en titt på de gjenværende oppgavene.

  • Lag en StarEmitter-forekomst - Vi skal instantiere StarEmitter klassen vi nettopp er ferdig med.
  • Tilordne et klokkeobjekt til emitteren - Vi ønsker en jevn hastighet av partikkelutslipp, så vi bruker SteadyClock-klassen. Parameteren som sendes til klokkeens konstruktør er utslippshastigheten, eller med andre ord antallet nye partikler opprettet i hvert emitterstrinn; en brøkdel på 0,5 betyr i hvert emitterstrinn, det er en 50% sjanse for at en ny partikkel skal opprettes og 50% sjanse for ingen partikkel opprettet.
  • Opprett en Renderer - For å visualisere partikkel-effekten, vil vi trenge en gjengivelse. DisplayObjectRenderer skal brukes sammen med DisplayObjectClass-initialiseringen: initieringsprogrammet tilordner et visningsobjekt til hver partikkel, og gjengivaren legger disse skjermobjektene til en containers visningsliste, og oppdaterer dem kontinuerlig. Ikke glem å legge emitteren til rendereren.
  • Ring hovedløkken gjentatte ganger - Dette siste skrittet holder Stardust oppe. Her skal vi gjøre bruk av enter-frame hendelsen.
  • Nedenfor er den komplette koden for dokumentklassen, nødvendige importopplysninger inkludert.

 pakke import flash.display.Sprite; importer flash.display.StageScaleMode; importere flash.events.Event; importer flash.geom.Rectangle; importer idv.cjcat.stardust.common.clocks.SteadyClock; importer idv.cjcat.stardust.common.renderers.Renderer; importer idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; offentlig klasse StarParticles utvider Sprite private var emitter: StarEmitter; offentlig funksjon StarParticles () // instantiate StarEmitter emitter = ny StarEmitter (ny SteadyClock (0.5)); // container sprite var container: Sprite = new Sprite (); // rendereren som gjør partikkel-effekten var renderer: Renderer = ny DisplayObjectRenderer (container); renderer.addEmitter (emitter); // legg beholderen til visningslisten over bakgrunnen addChildAt (container, 1); // gjøre bruk av enter-frame hendelsen addEventListener (Event.ENTER_FRAME, mainLoop);  privat funksjon mainLoop (e: Event): void // oppdater SinglePoint posisjonen til musposisjonen emitter.point.x = mouseX; emitter.point.y = mouseY; // ring hovedløkken emitter.step (); 

Endelig er vi ferdige! La oss nå se på resultatet. Trykk CTRL + ENTER i Flash for å teste filmen, og du får se resultatet.


Variasjon 1: Animerte stjerner

Vi er ikke ferdige ennå! La oss gjøre noen flere variasjoner. Den første bruker animerte filmklipp til partiklene våre.

Trinn 9: Lag en tidslinje-animasjon

Denne første varianten er ganske enkel, ikke med noen ekstra koding. Det er så enkelt som å lage en grunnleggende tidslinje animasjon. Rediger stjernesymbolet i Flash IDE, opprett en annen nøkkelramme, og endre stjernens farge i denne rammen til rød. Dette fører i hovedsak til at stjernene blinker mellom gul og rød. Du vil kanskje sette inn noen flere tomme rammer mellom, siden en bildefrekvens på 60 fps er for rask til en to-rammes blinkende.

Test nå filmen og sjekk resultatet. Den blinkende stjerneneffekten ser tegneserieaktig ut; Dette kan brukes til klassiske svimmelstjerner, som vanligvis ses i tegneserier.


Variasjon 2: Juster tidsskalaen dynamisk

Som nevnt tidligere, er en av Stardust-funksjonen "justerbar simuleringstidskala", som betyr at tidsskala brukt av Stardust for partikkel-simulering kan justeres dynamisk. Alt gjøres ved å endre egenskapen Emitter.stepTimeInterval, som er 1 som standard. Følgende kodestykke endrer denne verdien til 2, noe som resulterer i at partikler beveger seg dobbelt så fort og emitter oppretter nye partikler med dobbel hastighet.

 emitter.stepTimeInterval = 2;

I denne varianten lager vi en skyveknapp på scenen og bruker den til å dynamisk justere simuleringstidskalaen.

Trinn 10: Opprett en glidebryter

Dra en Slider-komponent ut fra komponentpanelet til scenen. Gi det navnet "glidebryteren".

Trinn 11: Parametere for oppsettsregulering

Vi ønsker at glidebryteren skal glide mellom 0,5 og 2, noe som betyr at vi vil at partikkelsimuleringen skal være minst halv så rask som normalt og maksimalt to ganger raskt. Sett også "liveDragging" til ekte slik at vi kan se oppdateringen når vi skrubbe skyveminnet.

Trinn 12: Slider Event Listener

Nå må vi lytte til glidebryterens endringshendelse for å dynamisk endre simuleringstidsskalaen. Først importerer du SliderEvent-klassen i dokumentklassen.

 importere fl.events.SliderEvent;

Og hør deretter på skyvebryterens endringshendelse i dokumentklassekonstruktøren.

 slider.addEventListener (SliderEvent.CHANGE, changeTimescale);

Endre endre simuleringstidskalaen i lytteren. Legg til følgende lytter i dokumentklassen.

 privat funksjon changeTimescale (e: SliderEvent): void emitter.stepTimeInterval = slider.value; 

La oss se på resultatet. Legg merke til at når du skrubber skyvekontrollens tommel til venstre, reduseres partikkel-simuleringen, og hvis du skrubber til høyre, går simuleringen raskere.


Variasjon 3: Flere skjermklasser

Stardust tilbyr en spesiell initialiserer kalt SwitchInitializer. Konstruktøren godtar to arrays som parametere; den første er en rekke initialiserere, og den andre, med samme lengde som den første, er en rekke "vekter". Hver gang Stardust bruker denne initialisatoren til å initialisere partikler, velges en av initialisatorene i den første gruppen tilfeldig for å initialisere partiklene. Jo mer vekt en initialiserer har, jo mer sannsynlig blir det plukket for initialisering. I denne varianten kommer vi til å få emitteren til å skytes ut, ikke bare stjerner, men også hvite sirkler.

Trinn 13: Tegn en sirkel

Tegn en hvit sirkel, konverter den til et symbol, eksportert for ActionScript, og merk symbolet og klassen "Sirkel". Dette er klassen vi skal bruke for de hvite sirkler.

Trinn 14: Opprett Switch Initializer

Åpne StarEmitter-klassen, og slett den følgende linjen. Dette deaktiverer DisplayObjectClass-initialisereren vi satt opp i de forrige trinnene.

 addInitializer (ny DisplayObjectClass (Star));

Legg nå følgende kode til konstruktøren. Vi vil gjerne ha stjerner og sirkler som skal sendes like sannsynlig, så vi gir dem begge en vekt på 1.

 // initialiseringen for stjerner var doc1: DisplayObjectClass = ny DisplayObjectClass (Star); // initialisatoren for hvite sirkler var doc2: DisplayObjectClass = ny DisplayObjectClass (Circle); // bryteren initialiseringen var si: SwitchInitializer = ny SwitchInitializer ([doc1, doc2], [1, 1]); // legg til bryteren initialiserer til emitter addInitializer (si);

Til slutt, test filmen. Du kan se både stjerner og sirkler blir sendt ut fra emitteren, se