Jeg er sikker på at Stage3D ikke er fremmed for de fleste lesere; Det er den nye API som gir AS3-programmerere tilgang til GPU. Imidlertid kan koding mot opkoder i Stage3D ikke være alles foretrukne valg, så det er heldig at det er en snarvei: Starling, et bibliotek utviklet for å inkapslere dette lavt nivå programmering for å gjøre det mye lettere. Og sammen med Starling kommer dens partikkeleffekter utvidelse. I denne veiledningen vil vi sjekke partikkelsystemene i dette rammeverket, og se programmene som er brukt på et skyte-opp-spill.
Hopp over dette trinnet hvis du har jobbet med FlashDevelop i noen tid. For nybegynnere, her er hvordan du installerer en bibliotekspakke - i dette tilfellet Starling og dets partikkelutvidelse. Vær oppmerksom på at disse to elementene ikke kommer i en pakke, så vi må laste dem ned separat.
Først, last ned Starling-rammeverket og dets partikkelutvidelse fra deres repositorier. Unzip etter vellykket nedlasting. Skann den første utpakket katalogen for src
mappe og lim inn Starling Framework-biblioteket, fremhevet i bildet nedenfor, i prosjektkildemappen.
Skann den andre mappen for partikkelutvidelsen, og kombiner dem sammen. Du kan trekke den uthevede mappen under i Starling
mappe. Bildet nedenfor er sluttresultatet du bør ankomme til.
For mer informasjon om FlashDevelop og bruk av eksterne biblioteker, se disse veiledningene:
Hvis du ikke har blitt introdusert til Starling og dens partikkelutvidelse allerede, anbefaler jeg sterkt et besøk til Lee Brimelows videoopplæringsprogrammer om Starling og partikkeleffekter, og Matthew Chungs veiledning om håndtering av animasjonsland med Starling.
Vi skal bare brise gjennom det grunnleggende i to trinn her. Hvis du allerede er kjent med Starling og dens partikkelforlengelse, kan du ikke hoppe til trinn 4.
Du kan se fra det andre bildet av det forrige trinnet (den nedre delen) at to klasser blir opprettet: Main.as
og Testing.as
. Den første fungerer som en lansering for sistnevnte. Så, de fleste av vår Starling-kode bor i Testing.as
. Jeg har markert den viktige koden i Main.as
her:
privat funksjon init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // inngangspunkt var myStarling: Starling = ny Starling (Testing, scenen); myStarling.simulateMultitouch = true; myStarling.start (); // start Starling på scenen // tillate mus / berøre hendelser å skje i Starling // sving nøkkel og start motoren!
... og Testing.as
skal se slik ut:
offentlig klasse Testing utvider Sprite public function Testing () addEventListener (Event.ADDED_TO_STAGE, init); privat funksjon init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // kode går her. stage.color = 0; // slå scenefarge til svart // Tegn litt quad på scenen, // for å sikre at alt er på plass // Merk øverst til venstre på sprite er justert til midten av scenen var q: Quad = ny Quad (30, 30); addChild (q); q.color = 0xEEEEEE; q.x = scene.stageWidth >> 1; q.y = scene.stageHeight >> 1;
Og hvis alt er satt opp riktig, bør du komme til resultatet som vist nedenfor. Ingenting mye, bare en sprite på scenen.
Merk: Testing.as
Utvider Sprite fra Starling.display.Sprite
, ikke flash.display.Sprite
. Klassene har samme navn, men er ikke det samme.
Partikkelforlengelsen av Starling inneholder tre viktige klasser. Deres funksjonaliteter er tabulert nedenfor.
Navn på klasse | funksjonalitet |
Particle.as | En enkeltpartikkel med unike egenskaper. |
ParticleSystem.as | Kontrollerer partikkeltrømmen: generasjon, animasjon og gjenvinning. |
ParticleDesignerPS.as | En forlengelse av ParticleSystem.as for å muliggjøre enkel manipulering av partikkelsystemet. |
Vi skal skape en forekomst av ParticleDesignerPS.as
. Dette krever innføring av følgende argumenter i klassekonstruktøren:
Ingen bekymringer, onebyonedesign.com vil hjelpe deg med dette. Besøk deres partikkel designer side og juster alle disse initieringsverdiene til ditt hjerte innhold. Deretter eksporterer du alle dataene til ZIP-format. Denne ZIP-filen vil inneholde XML-filen og bildet for partikkel-effekten du nettopp har designet gjennom deres nettside!
Unzip og trekk alle disse inn i kildemappen din i FlashDevelop. Se de uthevede elementene i bildet nedenfor.
Generer import uttalelser for å få disse to elementene i din testing
klasse. Du må også omskrive i det
metode i testing
. De er alle nedenfor.
[Embed (source = "particle.pex", mimeType = "application / octet-stream")] private var InitValues: Klasse [Embed (source = "texture.png")] privat var Eksempel: Klasse
privat funksjon init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // kode går her. stage.color = 0; // slå scenefarge til svart var flow1: ParticleDesignerPS = ny ParticleDesignerPS (XML (new InitValues ()), Texture.fromBitmap (new Sample ())); addChild (flow1); flow1.emitterX = stage.stageWidth >> 1; flow1.emitterY = stage.stageHeight >> 1; flow1.start (); Starling.juggler.add (flow1);
Her er resultatet du bør ankomme til. Snarere enkel, rett?
Vårt neste skritt er å aktivere samspill med partikkelsystemet (den lille brannen) ved kjøring. Vi bruker musen til å kontrollere egenskapene til brann. Men før vi gjør det, vil jeg gjerne sidetrakke litt for å fortelle deg om begrepet partikkelsystemer.
Partikler er bare sprites som kommer fra en koordinat. Etter fødselen vil de animere i et bestemt mønster. Dette mønsteret kan være unikt for hver partikkel eller felles for alle partikler. Men vær sikker på at deres fysiske egenskaper vil forandres over tid. For eksempel:
Også deres liv på scenen er bestemt ved fødselen. Hvis hver partikkel får lov til å leve for alltid på scenen, har vi overbefolkning og applikasjonsytelsen vil lide på grunn av at det har mange grafiske ressurser å håndtere. På et tidspunkt dør partikkelen, men det blir ikke spratt av scenen. Det blir resirkulert i stedet, ved å bli flyttet til en fødekoordinat og antar rollen som en ny partikkel. Det er en ny partikkel fordi et nytt sett med egenskaper blir definert for det, så før animasjonen starter og en annen syklus fortsetter.
(Dette er objekt pooling, og du kan se hvordan du bruker den til dine egne Flash-prosjekter uten stjerne her.)
Ok, så hvordan er dette relatert til brannen vår? Vel, vi kan bruke lette funksjoner for å animere egenskapene til denne brannen over tid. Innenfor Starling-rammen, ParticleDesignerPS
er plassert på slutten av dette hierarkiet:
ParticleDesignerPS
> ParticleSystem
> Displayobject
> EventDispatcher
> Gjenstand
For å finne en balanse, vil vi bare spore arvede egenskaper fra ParticleSystem
. La oss se på disse neste trinnene ...
ParticleSystem
og ParticleDesignerPS
Nedenfor er egenskapene til ParticleSystem
.
Eiendom | Beskrivelse |
kapasitet | Maksimale partikler som systemet kan bære når som helst. Øker i trinn på 500 når antall partikler overskrider sin nåværende kapasitet. Skrivebeskyttet. |
numParticles | Antall partikler i systemet på et gitt tidspunkt. Skrivebeskyttet. |
emissionRate | Antall partikler generert fra fødekoordinat hvert sekund. |
emitterX , emitterY | Kontrollpunkt for beholderen der alle partiklene lever. |
| Context3DBlendFactor definisjon for kilde og destinasjon. Destinasjon refererer til pikselfarge fra siste gjengivelse og kilde refererer til ny pikselfarge for å tegne på destinasjon. |
tekstur | Nåværende bilde samplet som tekstur av partikler. Skrivebeskyttet. |
De av ParticleDesignerPS
Tabuleres i neste tabell. De fleste av disse egenskapene kan finjusteres av start- og sluttstatus. For eksempel vil alle genererte partikler initieres med en størrelse på 1,0 og avslutte ved 0,1. Partikkelstrømmen vil imidlertid være kjedelig dersom alle partikler initieres og termineres ved slike lignende tilstander, så ParticleDesignerPS
Avsetninger for varians av den opprinnelige verdien, og noen ganger varians på terminasjonsverdi også.
Når vi oppgir deres eksempel, hvis vi gir en varians på 0,2 på partikkelens opprinnelige størrelse, vil konsekutive partikler som fødes eller resirkuleres inn i systemet starte deres størrelse et sted mellom 0,8 ~ 1,2 og slutte ved 0,1.
Eiendom | Beskrivelse |
emitterXVariance , emitterYVariance | Variasjon av fødekoordinaten. |
startSize , startSizeVariance | Innledende størrelse og varians |
endSize , endSizeVariance | Oppsigelsesstørrelse og varians |
emitAngle , emitAngleVariance | Partikkelens innledende retning og varians |
hastighet , speedVariance | Partikkelens innledende hastighet og varians |
gravityX | Akselerasjon langs x-aksen på alle partikkels initialhastighet |
gravityY | Akselerasjon langs y-aksen på alle partikkels initialhastighet |
tangentialAcceleration , tangentialAccelerationVariation | Rotasjonshastighet på partikkelhastighet og varians |
Det er to typer partikkelstrøm foreskrevet for ParticleDesignerPS
: tyngdekraften og radial. Vist i tabellen over er egenskaper du kan finjustere hvis du bruker tyngdekraftstrømmen. For tyngdekraften, er partikkoordinasjonen av partikler lokalisert på emitterX
og emitterY
. For radial er fødekoordinat for partikler plassert et stykke unna emitterX
og emitterY
, og de beveger seg mot den. Tabellen under viser egenskapene til radialstrømmen.
Eiendom | Beskrivelse |
maxRadius , maxRadiusVariance | Maksimal radius fra sentrum og varians |
minRadius | Minimum radius fra sentrum |
rotationPerSecond , rotationPerSecondVariance | Rotasjonshastighet på partikkelhastighet |
startColor , startColorVariance | Innledende farge og varians |
endColor , endColorVariance | Avslutning farge og varians |
Vel, takk for at du tok den lille omveien. Nå for noen ActionScript. I i det
metode, vil vi legge til en lytter på scenen for berøringshendelser.
stage.addEventListener (TouchEvent.TOUCH, spor);
Og lytteren som under.
privat funksjonsspor (e: TouchEvent): void var touch: Touch = e.getTouch (scene); // mapping på scenens koordinatnettet // når brukeren trykker på musen og beveger seg hvis (touch.phase == TouchPhase.MOVED) // beregne vinkelen til punktpartikkelstrømmen til var distX: Number = touch.globalX - flow1.emitterX; var distY: Number = touch.globalY - flow1.emitterY; varvinkel: Nummer = Math.atan2 (distY, distX); t = ny Tween (flow1, 1.5, Transitions.EASE_OUT_BACK); t.animate ("emitAngle", vinkel); Starling.juggler.add (t);
For å utføre animasjonen, a Tween
forekomst er definert. Dens manipulering er lik den populære Tween
motorer på mange måter. Deretter legger vi det til jongleren av nåværende forekomst av Starling. Dette jugglerobjektet vil bidra til å gradvis oppdatere Tween
forekomst over tid.
Resultatet er under. Klikk og dra musen rundt scenen.
La oss sette opp vårt skip nå og sette en sti på den. Aktivene er fra opengameart.org, og jeg har tatt med dem i nedlastingspakken. Sjekk det stedet for andre gratis spillkunst.
Vi starter på nytt med en annen klasse, TestingShip.as
. Først skal du importere romskipet "boss1.png".
[Embed (kilde = "boss1.png")] privat var Skip: Klasse
... etterfulgt av et lite oppsett for å initialisere det i i det
metode:
// oppsett grafisk utseende var shipBMP: Bitmap = nytt Ship () som Bitmap; // importer eiendel til en bmp var shipTEX: Texture = Texture.fromBitmap (shipBMP); // prøve bmp som tekstur til bilde var shipIMG: Image = nytt bilde (shipTEX); // bilde opprettet med tekstur // oppsett skipets orientering og posisjon shipIMG.rotation - = Math.PI * 0.5; // omdirigere bildet shipIMG.x - = shipIMG.width >> 1; // fordi bildet er opprinnelig i øverste venstre hjørne, send IMG.y + = shipIMG.height >> 1; // vi plasserer bildet theShip = new Sprite (); // og legg det inn i en sprite. Nå er registreringspunktet sentrert. theShip.addChild (shipIMG); // sprite plassert på scenen addChildAt (theShip, 0); // navigasjonsegenskaper til skip loc = ny Vector2D (stage.stageWidth >> 1, stage.stageHeight >> 1); lof = ny Vector2D (0, 10); updateShip ();
Oppdater posisjon og orientering i henhold til loc
(plassering) og lof
(siktelinjen).
privat funksjon updateShip (): void theShip.x = loc.x; theShip.y = loc.y; theShip.rotation = lof.getAngle ();
Igjen, klikk og dra i scenen for å se effekten:
Ok, skipets eksos er på toppen av selve skipet, og romskipet svarer ikke på museventyr. Vi løser det nå. Bare kompensere emitterX
og emitterY
av partikkelstrømmen litt avstand fra romskipet og oppdater romskipets rotasjon ved hjelp av lof
.
(Noter det lof
er oppdatert på mus hendelser. Du vil se skriptet neste trinn.)
privat funksjon updateShip (): void theShip.x = loc.x; theShip.y = loc.y; theShip.rotation = lof.getAngle (); // oppdater partikelsporet offset = ny Vector2D (60, 0); offset.setAngle (lof.getAngle ()); flow1.emitterX = loc.x - offset.x; flow1.emitterY = loc.y - offset.y;
La oss prøve å programmere skipnavigasjon nå, ved sending av en museventil. Jeg har bare kommentert de viktige linjene:
privat funksjonsspor (e: TouchEvent): void var touch: Touch = e.getTouch (scene); hvis (touch.phase == TouchPhase.MOVED) var distX: Number = touch.globalX - flow1.emitterX; var distY: Number = touch.globalY - flow1.emitterY; vinkel = Math.atan2 (distY, distX); t = ny Tween (flow1, 1.5, Transitions.EASE_OUT_BACK); t.animate ("emitAngle", vinkel + Math.PI); t2 = ny Tween (theShip, 1.5, Transitions.EASE_OUT); t2.moveTo (touch.globalX, touch.globalY); // flytt skipet t2.onUpdate = refresh // ring på denne funksjonen når tween engine kjører Starling.juggler.add (t); Starling.juggler.add (t2); // legg til i juggler privat funksjon oppdatering (): void loc.x = theShip.x; // Oppdater sted loc.y = theShip.y; lof.setAngle (vinkel); // oppdater orienteringsoppdateringShip (); // Oppdater
Og her er et show av sluttresultatet. Dra musen rundt scenen og romskipet vil gå dit.
La oss finjustere vår eksos. Når skipet er i bevegelse, vil utblåsningen definitivt blåse vanskeligere, ikke sant? Vi kan trekke opp emissionRate
og hastighet
når du flytter skipet og gå ned emissionRate
når den er stoppet. Her er arrangementet, uthevet:
t2 = ny Tween (theShip, 1.5, Transitions.EASE_OUT); t2.moveTo (touch.globalX, touch.globalY); // flytt skipet t2.onUpdate = refresh // ring på denne funksjonen når tween engine kjører t2.onStart = startState // når skipet begynner å flytte t2.onComplete = endState // når skip animasjon stopper
Og her kalles funksjonen på disse hendelsene.
privat funksjon startState (): void flow1.emissionRate = 250 flow1.speed = 100; privat funksjon endState (): void flow1.emissionRate = 50 flow1.speed = 10;
Klikk og dra igjen, og vær oppmerksom på lengden på eksos.
Partikler kan også uttrykke hvor raskt skipet beveger seg i forhold til omgivelsene. Sjekk ut produksjonen nedenfor. Klikk og dra musen rundt. Følg hastigheten som de omkringliggende partiklene beveger seg på. De øker når du samhandler med skipet, og bremser ned når du stopper samspillet. De orienterer også rotasjonen tilsvarende.
Konfigurering av denne effekten er relativt enkelt på appen som vises av onebyonedesign.com. Vi må imidlertid kodes noen ActionScript for å kunne endre det ved kjøring, og dette vil ta de neste trinnene.
Initieringen av partiklene følger et lignende format til det forrige eksempel. Du kan velge å finjustere effekten din med appen fra onebyonedesign.com og importere til scenen din. Jeg kodes bare rett inn i ActionScript for å lete.
envr = ny ParticleDesignerPS (XML (new InitValues ()), Texture.fromBitmap (new Sample ())); addChildAt (EnvR, 0); envr.blendFactorSource = Context3DBlendFactor.ONE envr.blendFactorDestination = Context3DBlendFactor.ONE envr.speed = 10; envr.speedVariance = 20; envr.startSize = 15; envr.startSizeVariance = 0; envr.endSize = 20; envr.endSizeVariance = 20 envr.lifespan = 5.0; envr.lifespanVariance = 4.0; envr.emissionRate = 10 envr.start (); Starling.juggler.add (EnvR);
Vi må også sette partikkelemitteren litt langt foran skipet.
envrLoc = ny Vector2D (100, 0); envrLoc.setAngle (vinkel);
Og oppdatere denne vektoren på kjøretid.
// Oppdater miljøet envr.gravityX = -40 * lof.x; // partikkel akselererer i motsatt retning envr.gravityY = -40 * lof.y; // av synlinjevektoren envr.emitterX = loc.x + envrLoc.x; envr.emitterY = loc.y + envrLoc.y;
Du ser, den emitterXVariance
og emitterYVariance
Behandle aksene separat. Dette betyr at hvis vi roterer romskipet, trenger vi noen måter å bestemme lengden på spredningen langs disse to aksene.
Sjekk nå vektoren for synlinje. Det er alltid vinkelrett på spredningen (den tynne mørke linjen). Vi kan skala opp denne vektoren tilsvarende og swizzle sin x og y med de av emitterens varians på startpunktet. Sjekk demoen nedenfor. Klikk og dra musen rundt. Du vil se partikkelstrømmen mer levende.
Til slutt, skala størrelsen på spredt opp og sett den litt lenger foran skipet, slik at spillerne ikke ser sitt utslippspunkt.
envrLoc = ny Vector2D (200, 0); envrLoc.setAngle (vinkel);
// oppdater spread spread = envrLoc.clone (); spread.scale (0,5); envr.emitterXVariance = spread.y; envr.emitterYVariance = spread.x;
Til slutt når skipet akselererer, la oss øke størrelsen på gravityX
og gravityY
, pluss eksos, tilsvarende.
hvis (touch.phase == TouchPhase.MOVED) var distX: Number = touch.globalX - flow1.emitterX; var distY: Number = touch.globalY - flow1.emitterY; vinkel = Math.atan2 (distY, distX); // animere eksosen t = ny Tween (flow1, 1.5, Transitions.EASE_OUT_BACK); t.animate ("emitAngle", vinkel + Math.PI); Starling.juggler.add (t); // kontroll av eksosstrømmen1.speed = 350; flow1.endSize = 70; // orient skipet og parallaxens vinkel lof.setAngle (vinkel); lof.setMagnitude (10); // juster størrelsen på akselerasjonen envrLoc.setAngle (vinkel); hvis (touch.phase == TouchPhase.ENDED) // kontroll eksosflow1.speed = 100; flow1.endSize = 10; lof.setMagnitude (5); // juster størrelsen på akselerasjonen
Når du utvikler seg i spillet, vil du definitivt ta treff og lide skade. Som skade blir alvorlig, vil du sende opp. En slik effekt kan genereres her; vi kan gjøre bruk av emissionXVariance
og emissionYVariance
å definere området for brenning. Jeg har markert dem i koden under.
envr = ny ParticleDesignerPS (XML (new InitValues ()), Texture.fromBitmap (new Sample ())); addChildAt (EnvR, 2); envr.blendFactorSource = Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA envr.blendFactorDestination = Context3DBlendFactor.ONE; envr.emitterXVariance = theShip.width >> 2; envr.emitterYVariance = theShip.height >> 2; envr.emitAngle = 0; envr.emitAngleVariance = Math.PI; envr.speed = 0; envr.startSize = 40; envr.startSizeVariance = 0; envr.endSize = 10; envr.endSizeVariance = 0 envr.lifespan = 5.0; envr.lifespanVariance = 3.0; envr.emissionRate = 10; envr.start (); Starling.juggler.add (EnvR);
Skade alvorlighetsgrad er angitt av området og intensiteten av brenning. Øk og senk emissionRate
å simulere dette. Jeg har lagt til kontroller på tastaturet "A" og "S" for å etterligne dette.
privat funksjonskontrollBurn (e: KeyboardEvent): void if (e.keyCode == Keyboard.A) if (envr.emissionRate < 150) envr.emissionRate += 10; if (envr.lifespan < 8) envr.lifespan += 0.5; if (e.keyCode == Keyboard.S) if(envr.emissionRate > 10) envr.emissionRate - = 10; hvis (envr.lifespan> 5) envr.lifespan - = 0.5;
Merk at hvis du øker levetiden til partikler, synes brannen å brenne mer intensivt. Vel, det tar tid å interpolere partikler fra den opprinnelige størrelsen til sluttstørrelsen, så hvis du øker levetiden, er det lenger å overgang fra større start til mindre endestørrelse. Da flere store partikler holder seg på samme sted lenger, blandes de sammen for å gi inntrykk av en mer intens brann.
Trykk på "A" -tasten for å se brannen brenne mer intensivt og "S" -tasten for å slukke litt. Eksosens farge har vært forandret, for å skille den fra brenneren:
Alle gode spill må ende på et tidspunkt. Uansett hvem som blir eliminert, bør en god eksplosjon for en finish ikke bli savnet. Så hva med en kjernefysisk soppsky? Klikk på demoen under for å se en.
La oss nå kode det.
Denne partikkelstrømmen er litt annerledes enn de vi har sett. Tidligere har vi brukt partikkelstrøm type 0 (tyngdekraften) og dette er type 1 (radial). Partiklene flytter faktisk til midten med konstant hastighet.
Jeg svingte vekseldivansen til sitt høyeste, slik at du kan se alle de dannede partiklene danner en sirkel. Da, ved å animere maksimal radius og minimale radius, bør disse partiklene leve over tid, ved hjelp av a Tween
, Vi oppnår dette resultatet.
eksplosjon = ny ParticleDesignerPS (XML (new InitValues ()), Texture.fromBitmap (new Sample ())); addChild (eksplosjon); explosion.emitterX = stage.stageWidth >> 1; explosion.emitterY = stage.stageHeight >> 1; eksplosjon.emitterType = 1; eksplosjon.emitAngle = 0; eksplosjon.emitAngleVariance = Math.PI; eksplosjon.maxRadius = 10; eksplosjon.maxRadiusVarians = 0; eksplosjon.minRadius = 0;
Her er koden for å utføre animasjonen.
privat funksjonsspor (e: TouchEvent): void var touch: Touch = e.getTouch (scene); hvis (touch.phase == TouchPhase.BEGAN) explosion.emitterX = touch.globalX; eksplosjon.emitterY = touch.globalY; explosion.start (); t = ny Tween (eksplosjon, 1,0, overganger.EASE_IN); t.animate ("maxRadius", 150); t.animate ("minRadius", 130); t.onStart = frys t.onComplete = nullstille; Starling.juggler.add (t); privatfunksjon fryser (): void stage.removeEventListener (TouchEvent.TOUCH, spor); Tilbakestilling av privat funksjon (): void stage.addEventListener (TouchEvent.TOUCH, spor); explosion.stop (); eksplosjon.maxRadius = 10; eksplosjon.minRadius = 0;
Så dette har vært en lang opplæring. La oss gjøre litt omtale her. Vi har gått gjennom:
Vi har dekket ganske mye her. Men et viktig aspekt jeg ikke har gått gjennom, er å strekke seg fra ParticleSystem
. Dette vil virkelig gi deg muligheten til å kode dine egne partikkelspor i stedet for å stole på ParticleDesignerPS
. Jeg må utsette dette til en annen opplæring.
Takk for at du leser og ser deg i neste opplæring. Gi kommentarer om feil og denne partikkelmotorens bruk i prosjektet ditt hvis du velger å vedta det.