Lag en Tower Defense spill i AS3: Sikt og Fire

Make et Tower Defense spill i AS3: Aim og Brann
Del
Del
to
Share < .no> Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Hei Flash-utviklere! I denne opplæringen serien skal vi gå gjennom prosessen med å utvikle en helt enkel Tower Defense spillet. I denne første delen av serien, vil vi lære hvordan du distribuerer tårn på spillet feltet, gi dem muligheten til å sikte på et objekt (i dette tilfellet, mus) og gjøre dem brann partikler.




Endelig resultat Forhåndsvisning

Når vi fullføre denne opplæringen, skal vi ha denne:

Klikk på en sirkel for å montere en turret på den. Legg merke til hvordan alle tårn rotere slik at de peker mot musepekeren. Klikk, og alle montert tårn vil fyre av en partikkel mot markøren



Trinn 1:.? Hva er et Tower Defense spill

Wikipedias definisjon oppsummerer det pent:
< p> Målet med Tower Defense-spill er å prøve å stoppe fiendene fra krysset et kart ved å bygge tårn som skyter på dem når de passerer.

Det er egentlig hva vi skal utvikle i denne opplæringen serien. Husk at vi refererer til tårnene som tårn i denne opplæringen

Forbannet Treasure er et godt eksempel på en TD spillet, hvis du fremdeles er usikker



Trinn 2:.. Setup - IDE

Før vi begynner å utvikle spillet, trenger vi å sette prosjektet på vår IDE. Jeg skal bruke FlashDevelop her. Hvis du ønsker å lese om hvordan du setter opp prosjektet på Flash Utvikle, må du ha en lese Trinn 1 og 2 av denne opplæringen, eller dette full guide til FlashDevelop.

Så nå du bør ha en hovedklasse, Main .as, med følgende kode:
pakke {import flash.display.Sprite; public class Hoved strekker Sprite {offentlig funksjon main (): void {}}}



Trinn 3: Forstå spillet Elements

For denne delen, vil spillet vårt har følgende spillelementer:


    Spill Field:. Området der alle spillelementer vil bli plassert

    Turret Placeholder:. Dette er et sted på spillet feltet, definert til å holde en turret

    turret. Våre våpen i spillet som kan plasseres på tårnplassholdere

    Bullet. Og til slutt, partiklene som tårn brann

    Alle de ovennevnte elementene vil bli opprettet i . den Main.as unntatt tårn som vil være en egen Turret klasse

    Kan starte koding nå



    Trinn 4: Opprette plassholdere

    Først vi ' vil opprette en funksjon som heter createTurretPlaceholder () som vil skape og tilbake oss en plassholder sprite. Legg til følgende hovedKlasse:
    privat funksjon createTurretPlaceholder (): Sprite {var plassholder: Sprite = new Sprite (); //Tegne grafikk Var g: Grafikk = placeholder.graphics; g.beginFill (0xCE7822); g.drawCircle (0, 0, 20); g.endFill (); returnere plassholder;}

    Denne funksjonen er bare å lage en Sprite variabel plassholder. Deretter bruke Action tegning API vi skape grafikken, som er en enkel sirkel. Endelig den returnerer som sprite



    Trinn 5:. Legge Noen Plassholdere

    Nå vil vi lage tre plassene med hjelp av tidligere funksjon og sette dem i forskjellige posisjoner på banen. Legg til følgende kode i main () konstruktør:
    Var PLACEHOLDER1: Sprite = createTurretPlaceholder ();

    I ovennevnte uttalelse skaper vi en variabel PLACEHOLDER1 av type Sprite som mottar en plassholder fra oven createTurretPlaceholder () -funksjonen.
    placeholder1.x = 200; placeholder1.y = 60;

    Vi posisjonerer plassholderen på feltet
    addChild (PLACEHOLDER1);..

    Og da vi legger plassholderen til scenen

    Ved hjelp av den samme koden, vi vil legge til to flere plassholdere til feltet - slik at main () funksjonen skal se slik ut:
    offentlig funksjon main () {var PLACEHOLDER1: Sprite = createTurretPlaceholder (); placeholder1.x = 200; placeholder1.y = 60; Var PLACEHOLDER2: Sprite = createTurretPlaceholder (); placeholder2.x = 60; placeholder2.y = 260; Var placeholder3: Sprite = createTurretPlaceholder (); placeholder3.x = 350; placeholder3.y = 260; addChild (PLACEHOLDER1); addChild (PLACEHOLDER2); addChild (placeholder3);}



    Trinn 6: Turret - Opprette Class

    Som jeg nevnte tidligere, turret kommer til å bli en egen klasse. Dette er fordi tårn må ha bestemte egenskaper og metoder for sine egne, og til å bli utvidet i fremtiden for å skape forskjellige typer tårn. Dette gjør dem til en perfekt kandidat til å bli definert i en egen klasse.

    Gå på og lage en ny klasse kalt Turret, avledet fra Sprite, i en fil som heter Turret.as. Det skal ha følgende grunnleggende koden:
    pakke {import flash.display.Sprite; public class Turret strekker Sprite {offentlig funksjon Turret () {}}}



    Trinn 7: Turret - The Graphics

    Nå som vi har basestruktur i Turret klassen, er neste skritt å gi turret noen grafikk. For at vi oppretter en ny funksjon kalt draw () i klassen. Så satte følgende funksjon like under konstruktør:
    privat funksjon draw (): void {var g: Grafikk = this.graphics; g.beginFill (0xD7D700); g.drawCircle (0, 0, 20); g.beginFill (0x800000); g.drawRect (0, -5, 25, 10); g.endFill ();}

    Som du kanskje har lagt merke til i koden, vi tegner en sirkel og et rektangel på den. Det er hvordan vår turret kommer til å se. Nå kaller vi denne funksjonen fra konstruktør selv
    offentlig funksjon Turret () {tegne (.); }



    Trinn 8: Lage en Ghost Turret

    Det neste vi gjør er å vise et spøkelse turret når vi sveve plassholderne som vi har satt på spillet feltet. Hva er et spøkelse turret? Vel, det er bare en gjennomsiktig turret som vises når svever musen på plassholderne, for å fortelle spilleren at en turret kan distribueres der.

    Til å begynne med dette, trenger vi et spøkelse turret. Gå videre og erklære en variabel for det i hovedklassen
    privat Var ghost_turret: Turret;

    Nå opprette en ny turret i main () konstruktør.
    Ghost_turret = new Turret ();

    Gi spøkelset turret noen egenskaper, slik at det ser ut som et spøkelse:
    ghost_turret.alpha = 0,5; ghost_turret.mouseEnabled = false; ghost_turret.visible = false;

    I koden ovenfor senke vi ned tettheten av turret halvparten (0,5) og sett mouseEnabled eiendommen av turret til false slik at spøkelset turret ikke mottar noen mus hendelser. Hvorfor? Vi vil se det senere. Og som spøkelset turret vil være usynlig som standard, vi skjule det

    Til slutt legger turret til visningslisten.
    AddChild (ghost_turret);

    Hoved konstruktør bør se omtrent slik ut :
    offentlig funksjon main () {var PLACEHOLDER1: Sprite = createTurretPlaceholder (); placeholder1.x = 200; placeholder1.y = 60; Var PLACEHOLDER2: Sprite = createTurretPlaceholder (); placeholder2.x = 60; placeholder2.y = 260; Var placeholder3: Sprite = createTurretPlaceholder (); placeholder3.x = 350; placeholder3.y = 260; addChild (PLACEHOLDER1); addChild (PLACEHOLDER2); addChild (placeholder3); ghost_turret = new Turret (); ghost_turret.alpha = 0,5; ghost_turret.mouseEnabled = false; ghost_turret.visible = false; addChild (ghost_turret);}

    Hvis du kjører filmen nå (Ctrl + Enter), er alt du vil se tre plassene på scenen. Kjedelig huh? Lar legge til litt interaktivitet



    Trinn 9:. Viser /skjuler Ghost Turret

    Vi ønsker spøkelset turret å vises når musen svever over en plassholder. Så la oss legge muse lyttere til hver plassholder i createTurretPlaceholder () -funksjonen like før den returnerer eksempel variable
    privat funksjon createTurretPlaceholder (): Sprite {var plassholder: Sprite = new Sprite ();. //Tegne grafikk Var g: Grafikk = placeholder.graphics; g.beginFill (0xCE7822); g.drawCircle (0, 0, 20); g.endFill (); placeholder.addEventListener (MouseEvent.MOUSE_OVER, showGhostTurret, falsk, 0, true); placeholder.addEventListener (MouseEvent.MOUSE_OUT, hideGhostTurret, falsk, 0, true); returnere plassholder;}

    Koden legger lyttere til MOUSE_OVER og MOUSE_OUT hendelser

    Neste vi definerer de to handler funksjoner for det samme.. Legg til følgende to funksjonene under createTurretPlaceholder () -funksjonen:
    privat funksjon showGhostTurret (e: MouseEvent = null): void {var target_placeholder: Sprite = e.currentTarget som Sprite; ghost_turret.x = target_placeholder.x; ghost_turret.y = target_placeholder.y; ghost_turret.visible = true;} private funksjon hideGhostTurret (e: MouseEvent = null): void {ghost_turret.visible = false;}

    hideGhostTurret () bare skjuler spøkelset turret, men hva som skjer i den showGhostTurret funksjon? Innbytteren
    Var target_placeholder:.. Sprite = e.currentTarget som Sprite;

    Vi får referansen til plassholderen på hvilken mus er med MouseEvent sin currentTarget eiendom, typecasted å Sprite
    ghost_turret.x = target_placeholder .x; ghost_turret.y = target_placeholder.y; ghost_turret.visible = true;

    Dette er enkelt ... vi posisjonere spøkelset turret til plassholder sin cordinates og gjøre den synlig. Kjør filmen, og du bør se spøkelset turret vises når svever over plassholderne. Nice



    Trinn 10: Distribuere Turrets

    Vårt neste mål er å distribuere en turret når en plassholder klikkes. Til det trenger vi en KLIKK lytteren på plassholderen. Men før at vi trenger en Array variabel som vil holde alle våre tårn, slik at vi kan referere til dem når som helst senere. Gjør man i hovedklassen
    private Var tårn:. Array = [];

    Så ved en annen lytteren rett under de to foregå lyttere vi har lagt i createTurretPlaceholder () -funksjonen:
    placeholder.addEventListener (MouseEvent. MOUSE_OVER, showGhostTurret, falsk, 0, true); placeholder.addEventListener (MouseEvent.MOUSE_OUT, hideGhostTurret, falsk, 0, true); placeholder.addEventListener (MouseEvent.CLICK, addTurret, falsk, 0, true);

    Erklærer addTurret () handler funksjon under hideGhostTurret () -funksjonen:
    privat funksjon addTurret (e: MouseEvent): void {}

    Nå kan skrive koden for funksjonen. Legg til følgende kode i addTurret () -funksjonen
    Var target_placeholder: Sprite = e.currentTarget som Sprite;

    Vi først få henvisning til plassholderen som ble klikket akkurat som vi gjorde i showGhostTurret () -funksjonen..
    Var turret. Turret = new Turret ();

    vi lage en ny turret i en variabel som heter turret
    turret.x = target_placeholder.x; turret.y = target_placeholder.y;

    Deretter plasserer vi tårnet ved koordinatene til target_placeholder
    addChild (turret).; turrets.push (turret);

    Når turret er opprettet, vi legger det til scenen og skyv den inn i matrisen

    Din addTurret funksjon skal se slik ut til slutt.
    privat funksjon addTurret (e: MouseEvent): void {var target_placeholder: Sprite = e.currentTarget som Sprite; Var turret: Turret = new Turret (); turret.x = target_placeholder.x; turret.y = target_placeholder.y; addChild (turret); turrets.push (turret);}

    En ting å merke seg her. Husk at vi setter mouseEnabled eiendom spøkelset turret til falsk? Hvis vi ikke hadde, ville spøkelset turret i mellom plassholder og mus har fanget klikk hendelsen, og dermed hindre hendelsen i å nå plassholder. Som et resultat CLICK lytteren knyttet til plassholderen ikke ville ha bli kalt.

    Du ønsker kanskje å fjerne KLIKK lytteren fra plassholder. Jeg har ikke gjort det her siden de nye turret blokker noen klikk, men hvis du bruker en annen turret design, er det en god idé.

    Vel dvs alt vi trenger for å plassere våre tårn. Prøv å kjøre filmen, og du bør være i stand til å distribuere tårn på plassholdere



    Trinn 11:. Making Turret Flytt

    For denne opplæringen vil vi gjøre turret roterer til ansikt muse . Vi vil holde rotasjonen funksjonalitet i en egen metode for Turret klassen. Denne metoden vil bli kalt oppdateringen ()

    Lar legge denne metoden til turret nå:
    offentlig funksjon oppdateringen (): void {var vinkel. Number = Math.atan2 (stage.mouseY - this.y , stage.mouseX - this.x) /Math.PI * 180; this.rotation = vinkel;}

    Alt vi gjør i ths funksjon er å beregne vinkelen på musen fra turret og sette turret vinkel til det. (Ta en titt på trigonometri for Flash utviklere hvis du ikke er sikker på hvordan dette fungerer.)

    Men legg merke til at vi ikke har kalt denne funksjonen fra hvor som helst og så skjer det ingenting ennå. Denne funksjonen vil bli kalt fra spillet loop som vi definerer neste. Lar gå



    Trinn 12: The Game Loop

    Hva er et spill loop? Dens en funksjon som er knytte til ENTER_FRAME hendelsen og så det blir kalt på hver ramme. Den oppdaterer alle elementene i spillet ... i vårt tilfelle, tårn. Flere detaljer i denne artikkelen

    Lag en funksjon som heter gameLoop () under Main () konstruktør som vil være en lytter til ENTER_FRAME tilfelle av filmen:.
    Privat funksjon gameLoop (e: Hendelses): void {}

    Nå som vi har lytteren funksjon definert, må vi legge det til tilsvarende arrangement. Vi gjør det i Main () konstruktør. Legg til følgende linje til Main () -funksjonen:
    offentlig funksjon main () {var PLACEHOLDER1: Sprite = createTurretPlaceholder (); placeholder1.x = 200; placeholder1.y = 60; Var PLACEHOLDER2: Sprite = createTurretPlaceholder (); placeholder2.x = 60; placeholder2.y = 260; Var placeholder3: Sprite = createTurretPlaceholder (); placeholder3.x = 350; placeholder3.y = 260; addChild (PLACEHOLDER1); addChild (PLACEHOLDER2); addChild (placeholder3); ghost_turret = new Turret (); ghost_turret.alpha = 0,5; ghost_turret.mouseEnabled = false; addChild (ghost_turret); stage.addEventListener (Event.ENTER_FRAME, gameLoop);}



    Trinn 13:. Oppdatere Alle Turrets

    Kan sette noen kode i vår gameLoop () -funksjonen
    for hver (var turret : Turret i tårn) {}

    Vi iterere over tårn array, som har referanser til alle tårn på scenen, med en for hver ... i løkke
    for hver (var turret. Turret i tårn) {turret.update ();}

    Og kalle oppdateringen () funksjonen til hver turret. Og vi er ferdig. Hvis du kjører filmen nå, bør du være i stand til å distribuere tårn som alltid står overfor musen. Noe sånt som dette:



    Trinn 14: Gjøre tårn Skyt

    Vårt neste mål er å gjøre tårn skyter kuler. På hvem? For denne opplæringen, vil vi sørge tårn skyte mot et punkt vi klikker på scenen. Vi vil gjøre dette slik:


      Legg til et klikk lytteren til scenen

      iterere over alle tårn i oven lytteren

      Beregn vinkel.. . fra klikket punktet til turret

      Opprett en ny kule og flytte det i riktig retning

      Lar erklære lytteren funksjon kalt shoot Legg funksjonen til hovedklassen.
      privat funksjon shoot (e: MouseEvent): void {}

      Og så feste ovenfor lytteren til CLICK ved scenen i main () konstruktør:
      stage.addEventListener (MouseEvent.CLICK, skyte); stage.addEventListener (Event.ENTER_FRAME, gameLoop);}



      Trinn 15: Opprette Bullet

      Før vi fortsetter å skrive koden for skyting i shoot () -funksjonen, vil vi definere en ny funksjon for å lage en kule, akkurat som vi gjorde for å skape en plassholder. Så satte følgende funksjon under createTurretPlaceholder ():
      privat funksjon createBullet (): Sprite {var bullet: Sprite = new Sprite (); //Tegne grafikk Var g: Grafikk = bullet.graphics; g.beginFill (0xEEEEEE); g.drawCircle (0, 0, 5); g.endFill (); returnere bullet; }

      Ikke mye her. Vi bare lage en ny Sprite, tegne en off-white farge sirkel inni den, og returnere den. Nå la oss fortsette å definere vår shoot () -funksjonen



      Trinn 16:.? Hvordan skyte

      På tide å legge noen kode for å skyte ()
      for hver (. Var turret: Turret i tårn) {}

      Først iterere vi i løpet av alle tårn på scenen ved hjelp av for hver ... i sløyfe
      Var new_bullet: Sprite = createBullet ();

      Nå for. hver turret skaper vi en kule ved hjelp av funksjonen vi opprettet tidligere
      new_bullet.rotation = turret.rotation;.

      Her vi lagrer verdien av turret rotasjon eiendom i kule rotasjon. Hvorfor? Vel ... roterende kulen er ikke det vi ønsker. Kulen må fortsette å bevege seg i retning bestemmes av turret, og for dette trenger vi turret rotasjon verdi fra den tiden det skutt kulen. Vi lagrer dette som kulen rotasjon for fremtidig bruk
      new_bullet.x = turret.x + Math.cos (new_bullet.rotation * Math.PI /180) * 25;. New_bullet.y = turret.y + Math. sin (new_bullet.rotation * Math.PI /180) * 25;

      Disse to linjene sette kulen utgangsstillingen, noe som er 25 bildeelementer bort fra dreieskiven i retning vendt (husk rotasjonen egenskapen). Igjen, les deg opp på trigonometri hvis dette er ukjent for deg
      addChild (new_bullet);.

      Og som vanlig siste trinnet, legger vi kula til scenen display liste

      Dette er hvordan. skyte () -funksjonen skal se slik ut:
      privat funksjon shoot (e: MouseEvent): void {for hver (var turret: Turret i tårn) {var new_bullet: Sprite = createBullet (); new_bullet.rotation = turret.rotation; new_bullet.x = turret.x + Math.cos (new_bullet.rotation * Math.PI /180) * 25; new_bullet.y = turret.y + tak i Math.sin (new_bullet.rotation * Math.PI /180) * 25; addChild (new_bullet); }}

      Hvis du kjører du spillet nå og klikk på en plassholder, vil turret få få utplassert - men oops ... vi har et problem her. En ekstra bullet også blir opprettet med turret. Lar fikse dette



      Trinn 17:.?. Hvorfor gjorde That Extra Bullet Vises

      For å forstå dette må vi forstå hendelsen forplantning i AS3

      Enhver hendelse som blir generert går gjennom tre faser: fange
      , target Hotell og boblende
      . Hendelsene starter fra den øverste overordnede av målet som genererte hendelsen. Den går gjennom alle de indre ordnede elementer, som er fange
      fase. Så det kommer til selve målet som er målrette
      fase. Deretter går arrangementet tilbake til toppen, passerer gjennom samme elementene i revers, som er boblende
      fase. I boblende
      fase, alle elementene som har en lytter definert for forplanter arrangementet bli utløst og sine lyttere blir henrettet.

      Vi har et KLIKK lytteren bundet til scenen og plassholderne. Men plassholderne er også barn av scenen. Så når vi klikker på eksempel, blir et klikk hendelsen genereres med målet som plassholder. Arrangementet forplanter fra scenen mot plassholder - fangst
      fase. Den når eksempel og dens CLICK handler, den addTurret () -funksjonen, blir henrettet og vi har en turret på scenen. Nå arrangementet forplanter seg bakover - boblende Anmeldelser fase - og når den når den scenen igjen den finner et klikk lytteren for det også, som blir henrettet. Som et resultat av shoot () -funksjonen blir henrettet og en kule blir lagt til scenen.

      Så dvs problemet, men hvordan å løse det? Det vi trenger å gjøre er å stoppe arrangementet videre forplantning når den når målet. Det betyr i addTurret () vi stoppe hendelsens utbredelse. Så gå videre og legge en linje på slutten av addTurret ():
      privat funksjon addTurret (e: MouseEvent): void {var target_placeholder: Sprite = e.currentTarget som Sprite; Var turret: Turret = new Turret (); turret.x = target_placeholder.x; turret.y = target_placeholder.y; addChild (turret); turrets.push (turret); e.stopPropagation ();}

      Den linjen vi har lagt stopper hendelsens utbredelse og det ikke kommer på scenen. For en mer helhetlig forståelse av hendelsen rammeverk i Actionscript 3.0 lese AS3 101 innlegg. La oss fortsette med spillet



      Trinn 18:. Making the Bullet Move

      Vi skaper kulen på å klikke på scenen, men det beveger seg ikke likevel. Vårt neste skritt er å legge til en hendelse lytteren til kulen som blir kalt på hver ramme og flytter den. Først erklærer vi en variabel for kulen hastighet. Legg den variable hvor de andre variabler deklareres:
      private Var ghost_turret: Turret; private Var tårn: Array = []; privat Var bullet_speed: uint = 3;

      Deretter legger du til følgende lytteren funksjonen til hovedklassen :
      privat funksjon moveBullet (e: Hendelses): void {var bullet: Sprite = e.currentTarget som Sprite; bullet.x + = Math.cos (bullet.rotation * Math.PI /180) * bullet_speed; bullet.y + = tak i Math.sin (bullet.rotation * Math.PI /180) * bullet_speed;}

      Hva vi gjør i denne lytteren er:

      Få referansen av kulen som lytteren ble utløst.

      Trinnvis kulen posisjon ved bullet_speed beløp i retning av kulen rotasjon.

      Til slutt fester du lytter vi nettopp opprettet til ENTER_FRAME tilfelle kulen i skyte () -funksjonen:
      privat funksjon shoot (e: MouseEvent): void {for hver (var turret: Turret i tårn) {var new_bullet: Sprite = createBullet (); new_bullet.rotation = turret.rotation; new_bullet.x = turret.x + Math.cos (new_bullet.rotation * Math.PI /180) * 25; new_bullet.y = turret.y + tak i Math.sin (new_bullet.rotation * Math.PI /180) * 25; new_bullet.addEventListener (Event.ENTER_FRAME, moveBullet, falsk, 0, true); addChild (new_bullet); }}

      Hvis du teste deg spillet nå, bør du se kuler bevegelige når du klikker på scenen. Men hvis du ser nøye, vil du legge merke til at kulene holde flytte en gang skapt ... selv etter at de går ut av det synlige sceneområdet. Vårt neste skritt er å ødelegge kulene så snart de forlater kino grenser



      Trinn 19:. Ødelegge Bullets

      Legg til følgende kode i slutten av moveBullet () -funksjonen :
      privat funksjon moveBullet (e: Hendelses): void {var bullet: Sprite = e.currentTarget som Sprite; bullet.x + = Math.cos (bullet.rotation * Math.PI /180) * bullet_speed; bullet.y + = tak i Math.sin (bullet.rotation * Math.PI /180) * bullet_speed; if (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) {bullet.removeEventListener (Event.ENTER_FRAME, moveBullet); bullet.parent.removeChild (bullet); bullet = null; }}

      Her sjekker vi om kulen er ute av scenen grenser. Hvis det er, fjerner vi det ENTER_FRAME lytter og fjerne selve kulen fra scenen. Vi har også satt kulen variabel til null, slik at kulen har ingen referanse til venstre og er tilgjengelig for søppelrydding.



      Konklusjon

      Vi har gjennomført vår grunnleggende Tower Defense spill hvor du kan distribuere tårn på spesifikke plassholdere som skyter mot et punkt vi klikker på scenen. ? Cool, huh

      I neste del vil vi legge fiender til spillet og intelligens til tårn, slik at de kan gjøre hva de antar å gjøre: forsvare. Også vi vil legge til noen flere elementer som gjør spillet ser mer komplett og kjølig. Inntil da, prøve å legge noen flere funksjoner til dette på egen hånd. Anmeldelser