Lag en Tower Defense spill i AS3: Fiender og Basic AI

Make et Tower Defense spill i AS3: Fiender og Basic AI
4
Del
6
Del

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

Hei Flash Developers, velkommen til den andre delen av min Tower Defense spillet opplæringen. I den første del, har vi utviklet den grunnleggende mekanisme for å skape tårn og gjøre dem til å skyte mot punktet av museklikk. Men det er ikke hva tårn er for! I denne delen vil vi utvide spillet til å omfatte fiender, grunnleggende kunstig intelligens (AI) i tårn, og noen flere spillelementer. Er du klar




Endelig resultat Forhåndsvisning

Dette er spillet vi skal lage i denne opplæringen:?

Klikk på den oransje sirkler for å plassere tårn. De røde sirklene er fiender, og tallet på hver representerer sin poeng



Trinn 1:. Recap

I forrige tutorial vi utviklet et spill som hadde plassholdere for tårn. Vi kunne distribuere tårn ved å klikke på disse plassene, og tårn rettet mot musepekeren og skjøt kuler mot punktet hvor brukeren klikket.

Vi avsluttet med en hovedklasse som hadde spillet loop og spillet logikk. Bortsett fra at vi hadde den Turret klassen som hadde ingenting mye bortsett oppdateringsfunksjonen som gjorde turret roterer



Trinn 2:. En separat Bullet Class

Vi har tidligere skapt kulene i Hoved klasse og festet en ENTER_FRAME lytteren å flytte den. Kulen hadde ikke nok egenskaper tidligere for å vurdere det en gjør en egen klasse. Men i et slikt spill kuler kan ha mange varianter som hastighet, skade, og så videre, så det er en god idé å trekke ut kula kode og kapsle den i en egen Bullet klasse. La oss gjøre det.

Opprett en ny klasse som heter Bullet, utvide Sprite-klassen. Den grunnleggende koden for denne klassen skal være:
pakke {import flash.display.Sprite; public class Bullet strekker Sprite {offentlig funksjon Bullet () {}}}

Neste vi sette inn koden for å tegne kule grafikk, tatt fra Main, i Bullet. Som vi gjorde med Turret klasse, skaper vi en funksjon som heter uavgjort i Bullet Klasse:
privat funksjon draw (): void {var g: Grafikk = this.graphics; g.beginFill (0xEEEEEE); g.drawCircle (0, 0, 5); g.endFill ();}

Og vi kaller denne funksjonen fra Bullet konstruktør:
offentlig funksjon Bullet () {tegne ();}

Nå legger vi noen egenskaper til kulen. Legg fire variabler: hastighet, speed_x, speed_y og skader, før Bullet konstruktør:
private Var hastighet: Number; private Var speed_x: Number; private Var speed_y: Number; offentlig Var skade:?. int;

Hva er disse variablene for

hastighet: Denne variabelen lagrer hastighet av kulen

speed_x og speed_y: Disse lagre x og y-komponentene av hastigheten, henholdsvis, slik at beregningen av å bryte hastighet i sine enkelte komponenter ikke behøver å gjøres igjen og igjen.

skader: Dette er hvor mye skade kulen kan gjøre til en fiende. Vi holder denne variabelen publikum som vi vil kreve dette i spillet vårt sløyfe i hovedklassen.

Vi initial disse variablene i konstruktøren. Oppdater Bullet konstruktør:
offentlig funksjon Bullet (vinkel: Number) {speed = 5; skade = 1; speed_x = Math.cos (vinkel * Math.PI /180) * hastighet; speed_y = tak i Math.sin (vinkel * Math.PI /180) * hastighet; tegne ();}

Legg merke til vinkelen variabel vi mottar i konstruktøren. Dette er den retningen (i grader), hvor kulen vil bevege seg. Vi bare bryte hastigheten til sin x og y-komponentene og cache dem for fremtidig bruk.

Det siste som gjenstår i Bullet klassen er å ha en oppdatering funksjon som skal kalles fra spillet sløyfe å oppdatere ( flytte) kulen. Legg til følgende funksjon på slutten av Bullet Klasse:
offentlig funksjon oppdateringen (): void {x + = speed_x; y + = speed_y;}

Bingo! Vi er ferdig med vår Bullet klasse



Trinn 3:. Oppdatering av hoved Class

Vi flyttet mye kule kode fra Main klassen til sin egen Bullet klasse, så mye koden forblir ubrukt i Main og mye må oppdateres.

Først slette createBullet () og moveBullet () funksjoner. Fjerner også bullet_speed variable

Deretter går du skyte funksjon og oppdatere den med følgende kode:.
Privat funksjon shoot (e: MouseEvent): void {for hver (var turret: Turret i tårn ) {var new_bullet: Bullet = new Bullet (turret.rotation); new_bullet.x = turret.x + Math.cos (turret.rotation * Math.PI /180) * 25; new_bullet.y = turret.y + tak i Math.sin (turret.rotation * Math.PI /180) * 25; addChild (new_bullet); }}

Vi ikke lenger bruke createBullet funksjon for å lage kule heller bruke Bullet konstruktør og bestå turret rotasjon til det som er i regi av kulen bevegelse og slik at vi ikke trenger å lagre den i kule rotasjon eiendom som vi gjorde tidligere. Også vi legger ikke noe lytteren til bullet som kulen vil bli oppdatert fra i spillet sløyfe neste



Trinn 4:. Lagre Bullet Referanser

Nå som vi trenger å oppdatere kuler fra spillet loop, trenger vi en referanse for dem som skal lagres et sted. Løsningen er den samme som for tårn: opprette en ny Array heter kuler og presse kulene på den så de er skapt.

Først erklære en rekke like under tårn rekke erklæring:
private Var ghost_turret: Turret; private Var tårn: Array = []; private Var kuler: Array = [];

Nå til befolke denne matrisen. Vi gjør det når vi oppretter en ny kule - så, i shoot-funksjonen. Legg til følgende rett før du legger kulen til scenen:
Var new_bullet: Bullet = new Bullet (turret.rotation); new_bullet.x = turret.x + Math.cos (turret.rotation * Math.PI /180) * 25; new_bullet.y = turret.y + tak i Math.sin (turret.rotation * Math.PI /180) * 25; bullets.push (new_bullet); addChild (new_bullet);



Trinn 5: Oppdater Bullets

Akkurat som hvordan vi oppdaterer tårn spillet loop, vil vi oppdatere kulene, også. Men denne gangen, i stedet for å bruke en for ... hver sløyfe, vil vi bruke en grunnleggende for loop. Før dette må vi legge til to variabler til toppen av spillet loop, slik at vi vet hvilke variabler som brukes i spillet loop og kan sette dem fri for søppelrydding
Var turret: Turret; Var bullet. Bullet;

Gå videre og legge til følgende kode på slutten av spillet sløyfe:
for (var i: int = bullets.length - 1; i > = 0; I--) {bullet = kuler [i]; if (bullet!) fortsetter; bullet.update ();}

Her krysser vi over alt kulene på scenen hver ramme og ringe sine oppdateringsfunksjon som gjør dem flytte. Merke seg her at vi iterate kuler array i revers. Hvorfor? Vi får se dette på forhånd.

Nå som vi har en turret variabel deklarert utenfor allerede, trenger vi ikke å erklære den igjen inne i for ... hver sløyfe av tårn. Endre den til:
for hver (turret i tårn) {turret.update ();}

Til slutt legger vi grensekontrollen tilstand; Dette var tidligere i kulen ENTER_FRAME men nå vi sjekke det i spillet bue:
if (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || kule. y > stage.stageHeight) {bullets.splice (i, 1); bullet.parent.removeChild (bullet); fortsette;}

Vi sjekke om kulen er ute av scenen sin grense, og i så fall må vi først fjerne sin henvisning fra kuler array ved hjelp av skjøte funksjon, og deretter fjerne kulen fra scenen og fortsette med neste iterasjon. Dette er hvordan spillet sløyfe ut:
privat funksjon gameLoop (e: Hendelses): void {var turret: Turret; Var bullet: Bullet; for hver (turret i tårn) {turret.update (); } For (var i: int = bullets.length - 1; i > = 0; I--) {bullet = kuler [i]; if (bullet!) fortsetter; bullet.update (); }}

Hvis du nå kjøre spillet, bør du ha samme funksjonalitet som i del 1, med kode som er mye mer rent og organisert



Trinn 6:. Presentere Enemy

Nå legger vi et av de viktigste elementene i spillet: Enemy. Første er å opprette en ny klasse som heter Enemy utvide Sprite klasse:
pakke {import flash.display.Sprite; public class Enemy strekker Sprite {offentlig funksjon Enemy () {}}}

Nå legger vi noen egenskaper til klassen. Legg dem før Enemy konstruktør:
private Var speed_x: Number; private Var speed_y: Number;

Vi initial disse variablene i Enemy konstruktør:
offentlig funksjon Enemy () {speed_x = -1,5; speed_y = 0; }

Neste skaper vi tegne og oppdatere funksjoner for Enemy klassen. Disse er svært lik de fra Bullet. Legg til følgende kode:
privat funksjon draw (): void {var g: Grafikk = this.graphics; g.beginFill (0xff3333); g.drawCircle (0, 0, 15); g.endFill ();} offentlig funksjon oppdateringen (): void {x + = speed_x; y + = speed_y;}



Trinn 7: Timing spill Hendelser

I spillet vårt trenger vi å ha mange hendelser som finner sted på bestemte tider eller gjentatte ganger med visse mellomrom. Slik timing kan oppnås ved hjelp av en tidsteller. Telleren er bare en variabel som blir økes som tiden går i spillet. Det viktige her er når og hvor mye mengde for å øke telleren. Det er to måter som timing er generelt gjort i spill. Tid basert og Frame basert

Forskjellen er at enheten av trinnet i tid basert spill er basert på sanntid (dvs. antall millisekunder passert), men i en ramme basert spill, er enheten i trinn basert på ramme enheter (dvs. antall rammer vedtatt).

For spillet vårt har vi tenkt å bruke en ramme basert teller. Vi vil ha en teller som vi vil øke etter én i spillet loop, som går hver ramme, og så vil i utgangspunktet gi oss antall bilder som er gått siden spillet startet. Gå videre og erklære en variabel etter de andre variabeldeklarasjoner i hovedklassen:
private Var ghost_turret: Turret; private Var tårn: Array = []; privat Var kuler: Array = []; privat Var global_time: Number = 0;

øke denne variabelen i spillet sløyfe på toppen.
global_time ++;

Nå basert på denne disken vi kan gjøre ting som å lage fiender, som vi vil gjøre neste



Trinn 8: La oss lage noen Enemies

Det vi ønsker å gjøre nå er å skape fiender på banen etter hvert to sekunder. Men vi har å gjøre med rammer her, husker du? Så etter hvor mange rammer skal vi skape fiender? Vel, er spillet vårt kjører på 30 FPS, og dermed økes den global_time teller 30 ganger hvert sekund. Et enkelt regnestykke forteller oss at 3 sekunder = 90 rammer

På slutten av spillet sløyfe legge til følgende hvis blokken.
If (global_time% 90 == 0) {}

Hva er som betingelse om? Vi bruker modulo (%) operatør, som gir resten av en divisjon - så global_time% 90 gir oss resten når global_time er delt ved 90. Vi sjekke om resten er 0, da dette bare vil være tilfelle når det er global_time en multippel på 90 - det vil si den tilstanden returnerer true når global_time lik 0, 90, 180 og så videre ... På denne måten oppnår vi en trigger på hver 90 frames eller 3 sekunder

Før vi skaper. fienden, erklærer en annen matrise kalles fiender like nedenfor tårn og kuler array. Dette vil bli brukt til å lagre referanser til fiender på scenen
private Var ghost_turret: Turret; private Var tårn:. Array = []; private Var kuler: Array = []; private Var fiender: Array = []; privat Var global_time: Antall = 0;

erklære også en fiende variabel på toppen av spillet bue:
global_time ++; Var turret: Turret; Var bullet: Bullet; Var fiende: Enemy;

Til slutt legger du til følgende kode inne i hvis blokken vi opprettet tidligere:
fiende = new Enemy (); enemy.x = 410; enemy.y = 30 + Math.random () * 370; enemies.push (fiende), addChild (fiende);

Her skaper vi en ny fiende, skal den plasseres tilfeldig på høyre side av scenen, skyv den i fiender array og legge den til scenen



Trinn 9: Oppdatere Enemies <. br>

Akkurat som vi oppdaterer kulene i spillet loop, oppdaterer vi fiender. Sett inn følgende kode under turret for ... hver sløyfe:
for (var j: int = enemies.length - 1; j > = 0; j--) {fiendens = fiender [J]; enemy.update (); if (enemy.x < 0) {enemies.splice (j, 1); enemy.parent.removeChild (fiende); fortsette; }}

Akkurat som vi gjorde en grense sjekk for kuler, sjekker vi for fiender også. Men for fiender vi bare sjekke om de gikk ut av venstre side av scenen, som de bare flytte fra høyre til venstre. Du skal se fiender som kommer fra høyre hvis du kjører spillet nå



Trinn 10:. Gi Enemies Noen Health on

Hver fiende har litt liv /helse og så vil våre. Vi vil også vise de resterende helse på fiender. Lar erklære noen variabler i Enemy klassen for helsen ting:
private Var health_txt: Textfield, private Var helse: int; private Var speed_x: Number; private Var speed_y: Number;

Vi initial helse variabel i konstruktør neste. Legg til følgende til Enemy konstruktøren:
helse = 2;

Nå initial vi helsen tekstvariabelen som skal vises på midten av fienden. Vi gjør det i trekningen funksjon:
health_txt = new Textfield (); health_txt.height = 20; health_txt.width = 15; health_txt.textColor = 0xFFFFFF; health_txt.x = -5; health_txt.y = -8; health_txt.text = helse + ""; addChild (health_txt);

Alt vi gjør er å lage en ny Textfield, satt sin farge, plassere den og sette tekst til den nåværende verdien av helse slutt legger vi en funksjon for å oppdatere fiendens helse:
offentlig funksjon updateHealth (beløp: int): int {helse + = beløp; health_txt.text = helse + ""; returnere helse;}

Funksjonen aksepterer et heltall for å legge til helse, oppdaterer helse tekst, og returnerer den endelige helse. Vi kaller denne funksjonen fra spillet vårt sløyfe for å oppdatere sin hver fiende helse og oppdage om det er fortsatt i live



Trinn 11:.. Skyting Enemies

Først kan endre vår shoot funksjon litt. Erstatte eksisterende shoot funksjonen med folowing:
privat funksjon shoot (turret: Turret, fiende: Enemy): void {var vinkel: Number = Math.atan2 (enemy.y - turret.y, enemy.x - turret. x) /Math.PI * 180; turret.rotation = vinkel; Var new_bullet: Bullet = new Bullet (vinkel); new_bullet.x = turret.x + Math.cos (turret.rotation * Math.PI /180) * 25; new_bullet.y = turret.y + tak i Math.sin (turret.rotation * Math.PI /180) * 25; bullets.push (new_bullet); addChild (new_bullet); }

shoot funksjon nå aksepterer to parametre. Den første er en referanse til en turret som vil gjøre skytingen; den andre er en referanse til en fiende mot som det vil skyte.

Den nye koden her er lik den som er til stede i Turret klassens oppdateringsfunksjonen, men i stedet for musen posisjon vi nå bruke fiendens cordinates. Så nå kan du fjerne all koden fra oppdateringsfunksjonen i Turret klassen.

Nå hvordan å lage tårn skyte på fiender? Vel logikken er enkel for spillet vårt. Vi gjør alle tårn skyte den første fienden i fiender array. Hva? Lar sette noen kode, og deretter prøve å forstå. Legg opp følgende linjer i slutten av for ... hver sløyfe brukes til å oppdatere tårn:
for hver (turret i tårn) {turret.update (); for hver (fienden i fiender) {shoot (turret, fiende); gå i stykker; }}

For hver turret vi nå oppdatere den, så iterate fiender array, skyte den første fienden i rekken og bryte fra loopen. Så egentlig hver turret skyter tidligst opprettet fiende som det alltid er i begynnelsen av tabellen. Prøv å kjøre spillet, og du bør se tårn skyte fiender.

Men vent, hva er det kule som strømmer? Ser ut som de skyter for fort. Innbytteren hvorfor



Trinn 12:. Turrets fotograferer Too Fast

Som vi vet, går spillet sløyfe hver ramme dvs. 30 ganger i sekundet i vårt tilfelle, så skytingen uttalelse vi lagt i forrige trinn blir kalt på hastigheten på spillet vårt sløyfe og dermed ser vi en strøm av kuler flyter. Ser ut som vi trenger en timing mekanisme inni tårn også. Bytte over til Turret klassen og legge til følgende kode:
private Var local_time: Antall = 0; privat Var reload_time: int;


    local_time: Vår disken heter local_time i motsetning til global_time i hoved klasse. Dette er av to grunner: For det første, fordi denne variabelen er lokale for Turret klasse; andre, fordi det går ikke alltid frem som vår global_time variabel - det vil nullstille mange ganger i løpet av spillet.

    reload_time: Dette er tiden som kreves av turret å lesse etter skyting noen kuler. Utgangspunktet sin tidsforskjellen mellom to kuleskudd av en turret. Husk alle tidsenheter i spillet vårt er i form av rammer.

    Trinnvis den local_time variabel i oppdateringsfunksjonen og initialisere reload_time i konstruktøren:
    offentlig funksjon oppdateringen (): void {local_time ++;} offentlig funksjon Turret () {reload_time = 30; tegne ();}

    Neste legge til følgende to funksjoner på slutten av Turret Klasse:
    offentlig funksjon isReady (): Boolean {return local_time > reload_time;} reset offentlig funksjon (): void {local_time = 0;}

    isReady returnerer true bare når gjeldende local_time er større enn reload_time, dvs. når turret har reloaded. Og tilbakestillingsfunksjonen bare nullstiller local_time variabel, for å starte den omlasting igjen

    Nå tilbake i hovedklassen, modifisere shoot koden i spillet sløyfe vi lagt i forrige trinn til følgende:.
    for hver (turret i tårn) {turret.update (); hvis fortsette (turret.isReady ()!); for hver (fienden i fiender) {shoot (turret, fiende); turret.reset (); gå i stykker; }}

    Så hvis nå turret er ikke klar (isReady () returnerer false), fortsetter vi med neste iterasjon av turret loop. Du vil se at de tårn brann på et intervall på 30 rammer eller en annen nå. Cool



    Trinn 13: Begrens Turret Range

    Likevel noe som ikke stemmer. Tårn skyte på fiender uavhengig av avstanden mellom dem. Hva mangler her er spekter
    av en turret. Hver turret bør ha sin egen serie inne som sin kan skyte en fiende. Legg til en annen variabel til Turret klasse kalt rekkevidde og sett den til 120 inne i konstruktøren:
    private Var reload_time: int; private Var local_time: Antall = 0; privat Var Område: int; offentlig funksjon Turret () {reload_time = 30; range = 120; tegne ();}

    Også legge til en funksjon som heter canShoot på slutten av klassen:
    offentlig funksjon canShoot (fiende: Enemy): Boolean {var dx: Number = enemy.x - x; Var dy: Number = enemy.y - y; if (Math.sqrt (dx * dx + dy * dy) < = range) return true; annet return false;}

    Hver turret kan skyte en fiende bare når det oppfyller visse kriterier - for eksempel kan du la turret shoot bare røde fiender med mindre enn halvparten av sine liv, og ikke mer enn 30px unna. All slik logikk for å avgjøre om turret er i stand til å skyte en fiende eller ikke vil gå i canShoot funksjonen, som returnerer sant eller usant i henhold til logikken.

    Vår Logikken er enkel. Hvis fienden er innenfor området return true; ellers return false. Så når avstanden mellom turret og fiende (Math.sqrt (dx * dx + dy * dy)) er mindre enn eller lik rekkevidde, den returnerer sant. Litt mer modifikasjon i skyte-delen av spillet bue:
    for hver (turret i tårn) {turret.update (); hvis fortsette (turret.isReady ()!); for hver (fienden i fiender) {if (turret.canShoot (fiende)) {shoot (turret, fiende); turret.reset (); gå i stykker; }}}

    Nå bare hvis fienden er innenfor rekkevidden til turret, vil turret shoot



    Trinn 14:. Collision Detection

    En meget viktig del av alle Spillet er dueller. I spillet vårt kollisjon sjekk er gjort mellom kuler og fiender. Vi kommer til å legge den dueller kode inne i for ... hver sløyfe som oppdaterer kulene i spillet loop.

    Logikken er enkel. For hver bullet traversere vi fiender matrise og sjekke om det er en kollisjon mellom dem. Hvis ja, fjerner vi den kule, oppdatere fienden helse og bryte ut av loopen for å sjekke andre fiender. La oss legge til noen kode:
    for (i = bullets.length - 1; i > = 0; I--) {bullet = kuler [i]; //Hvis kulen ikke er definert, fortsetter du med neste iterasjon if (kule!) Fortsetter; bullet.update (); if (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) {bullets.splice (i, 1); bullet.parent.removeChild (bullet); fortsette; } For (var k: int = enemies.length - 1; k > = 0; k--) {fiendens = fiender [k]; if (bullet.hitTestObject (fiende)) {bullets.splice (i, 1); bullet.parent.removeChild (bullet); if (enemy.updateHealth (-1) == 0) {enemies.splice (k, 1); enemy.parent.removeChild (fiende); }\t\t\tgå i stykker; }}}

    Vi bruker Action sin hitTestObject funksjon for å se etter kollisjon mellom kulen og fiende. Hvis Collsion inntreffer, blir kulen fjernet på samme måte som når det forlater trinnet. Den største fienden helse er så oppdateres ved hjelp av updateHealth metoden, der kulen skade på eiendom er passert. Hvis updateHealth funksjonen returnerer et heltall mindre enn eller lik 0, betyr dette fienden er død og så fjerner vi det på samme måte som i kule.

    Og vår dueller er ferdig!
    < hr>
    Trinn 15: Hvorfor Reversere "For" Loops

    Husk at vi traversere fiender og kuler i revers i spillet vårt loop?. La oss forstå hvorfor. La oss anta at vi brukte en stigende for loop. Vi er på indeksen i = 3 og vi fjerner en kule fra tabellen. Ved fjerning av elementet i stilling 3, er dens mellomrom fylles av elementet deretter i posisjon 4. Så nå elementet tidligere i posisjon 4 på 3. Etter at iterasjon i trinn av 1 og 4, og blir så element i posisjon 4 er sjekket.

    Oops, ser du hva som skjedde akkurat nå? Vi savnet element nå i posisjon 3 som flyttet tilbake som følge av spleising. Og så bruker vi en omvendt for løkke som fjerner dette problemet. Du kan se hvorfor



    Trinn 16:. Vise Turret sin Range

    La oss legge til noen ekstra ting å gjøre spillet ser bra ut. Vi vil legge til funksjonalitet for å vise en turret rekkevidde når musen svevde på den. Bytte over til Turret klassen og legge til noen variabler til det:
    private Var Område: int; private Var reload_time: int; private Var local_time: Antall = 0; privat Div kroppen: Sprite, private Var range_circle: Sprite;

    Neste oppdatere trekningen funksjonen til følgende:
    privat funksjon draw (): void {range_circle = new Sprite (); g = range_circle.graphics; g.beginFill (0x00D700); g.drawCircle (0, 0, range); g.endFill (); range_circle.alpha = 0,2; range_circle.visible = false; addChild (range_circle); Kroppen = new Sprite (); Var g: Grafikk = body.graphics; g.beginFill (0xD7D700); g.drawCircle (0, 0, 20); g.beginFill (0x800000); g.drawRect (0, -5, 25, 10); g.endFill (); addChild (kroppen); }

    Vi bryter grafikken i turret i to deler: kroppen og utvalget grafikken. Vi gjør dette for derved å gi en bestilling til de forskjellige deler av tårnet. Her trenger vi range_circle å være bak turret kropp, og så legger vi det først til scenen. Til slutt legger vi to muse lyttere å veksle området grafisk:
    privat funksjon onMouseOver (e: MouseEvent): void {range_circle.visible = true;} private funksjon onmouseout (e: MouseEvent): void {range_circle.visible = false;}

    Nå feste lyttere til de respektive hendelser på slutten av konstruktøren:
    body.addEventListener (MouseEvent.MOUSE_OVER, onMouseOver); body.addEventListener (MouseEvent.MOUSE_OUT, onmouseout);

    Hvis du kjøre spillet og prøve å distribuere en turret, vil du se en flimrende når svever på plassholdere. Hvorfor er det
    Se flimringen
    Trinn 17:? Fjerne Flicker

    Husk at vi setter mouseEnabled eiendom spøkelset turret til falsk? Vi gjorde det fordi, spøkelset turret ble fange mus hendelser ved å komme i mellom mus og plassholderen. Den samme situasjonen har kommet igjen som turret selv har to barn nå - sin kropp og utvalget sprite -. Som er fange mus hendelser i mellom

    Løsningen er den samme. Vi kan sette sine individuelle mouseEnabled eiendommer til false. Men en bedre løsning er å sette spøkelset turret sin mouseChildren eiendom til false. Hva dette er sperre for alle barn spøkelse turret fra å motta mus hendelser. Ryddig, ikke sant? Gå videre og sett den til false i hoved konstruktør:
    ghost_turret = new Turret (); ghost_turret.alpha = 0,5; ghost_turret.mouseEnabled = false; ghost_turret.mouseChildren = false; ghost_turret.visible = false; addChild (ghost_turret);

    Problem løst

    Trinn 18: Hva Neste

    Vi kunne forlenge denne demoen til å omfatte mye mer avanserte funksjoner og slå den inn i en spillbar spill.?. Noen av disse kan være:


      Bedre AI logikk for å velge og skyte fiender

      Ulike typer tårn, kuler og fiender i spillet

      Complex fiende.. baner i stedet for rette linjer.

      La oss se hva du kan komme opp med fra denne grunnleggende demo. Jeg vil være glad for å høre om du Tower Defense-spill, og dine kommentarer eller forslag til serien.