Genererer spøkelsene som følger i dine Footsteps

Generating spøkelsene som følger i dine fotspor
Del
Del
4
Del

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

Bane følgende er et enkelt konsept å forstå. Objektet beveger seg fra punkt A til punkt B til punkt C, og så videre. Men hva hvis vi ønsker at våre objekt til å følge stien av spilleren, som spøkelser i bilspill? I denne opplæringen, vil jeg vise deg hvordan du kan oppnå dette med veipunkter i AS3.




Endelig resultat Forhåndsvisning

Klikk på SWF, og deretter bruke pil tastene for å bevege deg rundt. Trykk space for å bytte til spøkelset, som vil følge stien du har opprettet.



Logikken bak Sti Etter

La oss anta at spilleren beveger seg 4 enheter igjen og 2 enheter ned fra vårt synspunkt opprinnelse. For vår spøkelse for å ende opp på samme sted vil det måtte også flytte 4 enheter igjen og 2 enheter ned fra samme utgangspunktet. Nå la oss si at vår spiller beveger seg med en hastighet på 2; for banen etter å forbli nøyaktig vår ånd vil også ha en hastighet hastighet på 2.

Hva om vår spiller bestemmer seg for å ta en pause før du fortsetter på? Den åpenbare løsningen er for spøkelset å holde styr på spillerens eksakte posisjon hver tick - men dette vil innebære lagring av store datamengder. I stedet, hva vi skal gjøre er rett og slett lagre data hver gang spilleren trykker annerledes nøkler Anmeldelser - så hvis spilleren beveger seg riktig i ti sekunder, vil vi lagre den samme mengden data som om spilleren flyttet rett for et halvt sekund

For denne teknikken til å jobbe oss spøkelse må rette seg etter følgende regler:.

Spøkelset og spilleren har samme utgangspunkt som
Spøkelset må følge nøyaktig samme bane som spilleren.

Spøkelset skal bevege seg i samme hastighet som spilleren.

Spøkelset har til å lagre gjeldende klokkeslett hver gang spillerens bevegelse endringer



Trinn 1:. Klar

Start med å lage en ny Flash-fil (Actionscript 3.0). Sett bredden til 480, høyden til 320 og rammer per sekund til 30. La bakgrunnsfargen som hvit og lagre filen som CreatingGhosts.fla; slutt satt sin klasse CreatingGhosts.

Før vi går inn i de klassene vi trenger for å lage et par movieclips. Start med å tegne to separate 20px torg uten et slag. Konvertere den første fyllet til en MovieClip, sette registreringen til sentrum, og kalte den spiller og eksportere den for Action med klassenavnet Player. Nå gjentar den samme prosessen, bortsett erstatte navnet med spøkelse og klassen med Ghost. Fjern disse movieclips fra scenen

Lag dokumentet klassen med følgende kode:..
Pakke {import flash.display *; import flash.events. *; public class CreatingGhosts strekker MovieClip {public Var spiller: Spiller = new Player (); offentlig funksjon CreatingGhosts () {addChild (spiller); }}}

Selvforklarende; vårt neste skritt vil være å sette opp spilleren klassen.
pakke {import flash.display *; import flash.events. *; import flash.geom.Point; import flash.ui.Keyboard; import flash.utils.Timer; import flash.utils.getTimer; public class Player strekker MovieClip {offentlig Var startPos: Point; offentlig Var Starttime: int; Var hastighet offentlig: Number = 2; offentlig Var currentLife: int; offentlig Var keyPressLeft: Boolean = false; offentlig Var keyPressRight: Boolean = false; offentlig Var keyPressUp: Boolean = false; offentlig Var keyPressDown: Boolean = false; offentlig funksjon Player () {}}}

De tre første variablene er vant til å bidra til å oppfylle reglene; startPos er vårt utgangspunkt som er starttid den tiden da spilleren ble lagt til scenen og hastighet er vår vår rente av bevegelse. currentLife er et tillegg brukes til å sjekke hvor mange ganger spilleren har dødd, derfor hver bane er lagret og tilgjengelig gjennom denne verdien. De siste fire variabler brukes til å sjekke tastetrykk

Det er på tide å lage Ghost klassen:..
Pakke {import flash.display *; import flash.events. *; import flash.geom.Point; import flash.utils.getTimer; import flash.utils.Timer; public class Ghost strekker MovieClip {statiske offentlig Var veipunkter: Array = new Array (); statiske offentlig Var ganger: Array = new Array (); offentlig Var i: int = 0; offentlig Var Starttime: int; Var hastighet offentlig: Number = 2; offentlig Var selectedLife: int; offentlig funksjon Ghost () {}}}

De to statiske variabler, veipunkter og tider, vil bli brukt til å lagre arrays; Den første vil lagre koordinatene til spillerens posisjoner når spilleren endrer bevegelse, og den andre vil lagre gangene hvor hver endring inntraff. De andre variablene matche de fra spiller klassen



Trinn 2:. Initial spilleren

Innenfor spillerens konstruktør legge til følgende linje:
addEventListener (Event.ADDED_TO_STAGE, init );

Neste lage init () -funksjonen:
offentlig funksjon init (e: Hendelses) {}

Først må vi få tak i Starttime og trykker på en ny tid matrise til Ghost ganger array. (Dette er litt forvirrende, spøkelset har flere tids arrays for å tillate det å håndtere flere liv i fremtiden.)
Starttime = flash.utils.getTimer (); Ghost.times.push (ny Array); currentLife = Ghost.times.length - 1; Ghost.times [currentLife] .push (flash.utils.getTimer () - Starttime);

Starttime er satt til gjeldende tid (en verdi i millisekunder); vi legger til et nytt barn matrise til Ghost ganger matrise; vår currentLife er satt til indeksen for dette nye utvalget; og vi skyver den tiden som har gått i løpet av denne funksjonen til det første elementet i dette nye utvalget

Nå har vi satt opp utgangsposisjonen.
startPos = new Point (stage.stageWidth /2, scenen. stageHeight /2); this.x = startPos.x; this.y = startPos.y; Ghost.waypoints.push (ny Array); Ghost.waypoints [currentLife] .push (startPos);

Vår utgangspunktet settes til midten av scenen; vi flytter vår Player til opprinnelse; en ny matrise er lagt til veipunkter array i Ghost klassen; og den første posisjonen er presset til denne matrisen.

Så, i øyeblikket, Ghost.times [0] [0] inneholder antall millisekunder siden SWF ble satt opp (praktisk talt null), og Ghost. veipunkter [0] [0] inneholder et punkt satt til midten av scenen.

Vårt mål er å kode dette slik at hvis, etter ett sekund, presser spilleren en nøkkel, så Ghost.times [0 ] [1] vil bli satt til 1000, og Ghost.waypoints [0] [1] vil være en annen Point, igjen satt til midten (fordi spilleren ikke vil ha flyttet ennå). Når spilleren slipper den tasten (eller trykker en annen), Ghost.times [0] [2] vil bli satt til gjeldende tid, og Ghost.waypoints [0] [2] vil være et punkt som matcher spillerens posisjon på den tiden

Nå, her er de tre hendelsen lyttere.
addEventListener (Event.ENTER_FRAME, enterframe), stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDown); stage.addEventListener (KeyboardEvent.KEY_UP, keyUp);



Trinn 3: Viktige hendelser

For nå la oss ignorere enterframe og fokus på tastetrykkene
offentlig funksjon keyDown (e: KeyboardEvent) {if (e.keyCode. == Keyboard.LEFT & & keyPressLeft == false) {updateWaypoints (); keyPressLeft = true; } else if (e.keyCode == Keyboard.RIGHT & & keyPressRight == false) {updateWaypoints (); keyPressRight = true; } If (e.keyCode == Keyboard.UP & & keyPressUp == false) {updateWaypoints (); keyPressUp = true; } else if (e.keyCode == Keyboard.DOWN & & keyPressDown == false) {updateWaypoints (); keyPressDown = true; } If (e.keyCode == Keyboard.SPACE) {ødelegge (); }}

Bare noen enkle hvis-setninger for å hindre insekter i tastetrykk, og to nye funksjoner som blir kalt. updateWaypoints () vil bli kalt hver gang nye poeng og tidene er å bli presset til ghost arrays, og ødelegge () brukes til å fjerne spilleren og legge til Ghost til scenen. Men før vi går til disse funksjonene la oss fullbyrde nøkkelpresse funksjoner
offentlig funksjon keyUp (e: KeyboardEvent). {If (e.keyCode == Keyboard.LEFT & & keyPressLeft == true) {updateWaypoints (); keyPressLeft = false; } else if (e.keyCode == Keyboard.RIGHT & & keyPressRight == true) {updateWaypoints (); keyPressRight = false; } If (e.keyCode == Keyboard.UP & & keyPressUp == true) {updateWaypoints (); keyPressUp = false; } else if (e.keyCode == Keyboard.DOWN & & keyPressDown == true) {updateWaypoints (); keyPressDown = false; }}

Denne gangen gjør vi det motsatte: variablene er satt til false når nøkkelen er utgitt, og listen er oppdatert

Jeg vil utdype nærmere på hva som skjer mellom disse funksjonene.. Hver gang du trykker på en tast veipunkt og tider er oppdatert, så hvis du trykker på en annen for å forårsake en endring et punkt og den tilsvarende tid er lagt til ghost arrays.

Men hva skjer hvis spilleren bestemmer seg for å tilfeldig frigjøre en tast og føre til endring igjen? Vel, vi står for at ved å oppdatere veipunkter og tider igjen. Hvis dette ikke var gjort Ghost ikke ville være i stand til å gjøre rede for 90 graders svinger; stedet det ville flytte på en vinkel mot neste punkt



Trinn 4:. Oppdatere og ødelegge

Våre updateWaypoints () -funksjonen er ganske enkel, ettersom den består av kode som vi har allerede skrevet:
offentlig funksjon updateWaypoints () {Ghost.times [currentLife] .push (flash.utils.getTimer () - Starttime); Ghost.waypoints [currentLife] .push (ny Point (this.x, this.y));}

ødelegge () -funksjonen er like enkelt! Veipunkter er oppdatert, et spøkelse er lagt til, event lyttere blir stoppet og vår spiller blir fjernet:
offentlig funksjon ødelegge () {updateWaypoints (); Var spøkelse: Ghost = new Ghost (); parent.addChild (ghost); removeEventListener (Event.ENTER_FRAME, enterframe); stage.removeEventListener (KeyboardEvent.KEY_DOWN, keyDown); stage.removeEventListener (KeyboardEvent.KEY_UP, keyUp); parent.removeChild (denne);}



Trinn 5: Spillerens enterframe

Begynn med å lage funksjonen:
offentlig funksjon enterframe (e: Hendelses) {}

For I denne opplæringen vil vi legge til noen enkle kollisjon med grenser, for å vise hvordan listen er oppdatert på denne endringen:
if ((this.x- (this.width /2)) > 0) {} if ( (this.x + (this.width /2)) < stage.stageWidth) {} if ((this.y- (this.height /2)) > 0) {} if ((this.y + (dette. høyde /2)) < stage.stageHeight) {}

Nå er spilleren skal kun bevege seg i den angitte retningen, mens det ikke berører en grense. Inne i første if-statement legge til følgende kode for å flytte venstre:
if (keyPressLeft == true) {if ((this.x- (this.width /2)) < = 0) {updateWaypoints (); this.x = this.width /2; } else {this.x - = hastighet; }}

Først vi sjekke om venstre tast er for øyeblikket nede, så vi sjekker for å se om spillerens posisjon er større enn eller lik 0; hvis så vi oppdaterer våre veipunkter og flytte spilleren til kanten av venstre side; hvis ikke vi fortsetter å flytte spilleren venstre

Nøyaktig det samme er gjort for de tre andre sidene.
if (keyPressRight == true) {if ((this.x + (this.width /2)) > = stage.stageWidth) {updateWaypoints (); this.x = (stage.stageWidth - (this.width /2)); } else {this.x + = hastighet; }} if (keyPressUp == true) {if ((this.y- (this.height /2)) < = 0) {updateWaypoints (); this.y = this.height /2; } else {this.y - = hastighet; }} if (keyPressDown == true) {if ((this.y + (this.height /2)) > = stage.stageHeight) {updateWaypoints (); this.y = (stage.stageHeight - (this.height /2)); } else {this.y + = hastighet; }}

Og med at vi er ferdig med spilleren Class



Trinn 6: Initial Ghost

Legg til følgende linje inne i Ghost konstruktør:
addEventListener (Event.ADDED_TO_STAGE, init);

Som før lage init () -funksjonen:
offentlig funksjon init (e: Hendelses) {selectedLife = times.length - 1; this.x = veipunkter [selectedLife] [0] .x; this.y = veipunkter [selectedLife] [0] .Y; Starttime = flash.utils.getTimer (); addEventListener (Event.ENTER_FRAME, enterframe);}

Vi starter med å velge den veien vi ønsker å bruke (som standard vil velge det siste array); vi deretter posisjonere spøkelset til opprinnelsen og sette vår Ghost starttid. Så en hendelse lytteren for enterframe er opprettet



Trinn 7:. The Ghost er enterframe

Naturligvis vi skaper vår enterframe funksjon:
offentlig funksjon enterframe (e: Hendelses) { }

Nå må vi sløyfe gjennom vår tid array. Dette gjør vi gjennom den variable i; vi sjekke om det er mindre enn lengden på array og vi sjekker også om medgått tid er større enn eller lik gjeldende tid i rekken:
stund (i < ganger [selectedLife] .length - 1 & & flash.utils.getTimer () - Starttime > = ganger [selectedLife] [i]) {i ++;}

Det neste du må gjøre er å flytte Ghost dersom medgått tid er mindre enn gjeldende tid fra tabellen:
if (flash.utils.getTimer () - Starttime < ganger [selectedLife] [i]) {updatePosition ();}



Trinn 8: Oppdatere Ghost posisjon Anmeldelser

Vi starter dette trinnet med å lage den updatePosition () -funksjonen:
offentlig funksjon updatePosition () {}

Neste legge to variabler, for å representere forskjellen og avstanden mellom den gamle og den nye posisjonen :
Var diff: Point = veipunkter [selectedLife] [i] .subtract (ny Point (this.x, this.y)); Var dist = diff.length;

Vi trekker poeng fra hverandre for å finne avstanden. Nå må vi flytte spøkelset:
if (dist < = hastigheten) {this.x = veipunkter [selectedLife] [i] .x; this.y = veipunkter [selectedLife] [i] .Y;} else {diff.normalize (1); this.x + = diff.x * hastighet; this.y + = diff.y * hastighet;}

Først sjekker vi om avstanden er mindre enn hastigheten (dvs. avstanden spøkelset flytter hvert tick); hvis så vi flytter Ghost direkte til poenget. Men hvis avstanden er mindre enn vi normalisere forskjellen ("betyr å gjøre dens størrelse være lik en, samtidig som man beholder den retning og følelse av vektoren» - euklidske Vektorer i Flash), og vi øker ånds posisjon langs retningen . av poenget




Trinn 9: A Side Note

Noe å merke seg om denne metoden er at den bruker mye CPU-ressurser til kontinuerlig lastetider og poeng, og til tider kan produsere noen lag selv om logikken er riktig. Vi fant to måter å motvirke dette, men

Den første er å sette din SWF å være ukomprimert i Publish Settings!; Dette vil resultere i en lengre lastetid ved oppstart imidlertid ytelsen blir jevnere. Den andre er mer å foretrekke hvis du har planer om å kompilere prosjektet som en exe for frakoblet bruk: bare øke bildefrekvensen til noe rundt 60.



Konklusjon:

Takk for at du tok deg tid til å lese denne opplæringen! Hvis du har spørsmål eller kommentarer kan du la dem nedenfor. Og hvis du ønsker en ekstra utfordring kan du prøve å sette opp Ghost klassen til å følge stiene i revers, eller i sakte film. Anmeldelser