Hei Flash-utviklere, velkommen til den andre delen av min Tower Defense Game-opplæring. I første del utviklet vi den grunnleggende mekanismen for å skape tårn og få dem til å skyte mot museklikkpunktet. Men det er ikke det tårnene er for! I denne delen vil vi utvide spillet for å inkludere fiender, grunnleggende kunstig intelligens (AI) i tårn og noen flere spillelementer. Er du klar?
Dette er spillet vi skal lage i denne opplæringen:
Klikk på oransje sirkler for å plassere tårn. De røde sirkler er fiender, og tallet på hver representerer sine treffpunkter.
I den forrige opplæringen utviklet vi et spill som hadde plassholdere for tårnene. Vi kunne distribuere tårnene ved å klikke på disse plassholderne, og tårnene rettet mot musepekeren og skuddkulene mot det punktet hvor brukeren klikket.
Vi avsluttet med a Hoved
klasse som hadde spillsløyfen og spilllogikken. Bortsett fra det hadde vi turret
klasse som ikke hadde noe mye bortsett fra Oppdater
funksjon som gjorde tårnet rotere.
Vi har tidligere opprettet kulene i Hoved
klasse og vedlagt en ENTER_FRAME
lytter til å flytte den. Kulen hadde ikke nok egenskaper tidligere til å vurdere det å lage en egen klasse. Men i et slikt spill kan kuler ha mange varianter som fart, skade og så videre, så det er en god ide å trekke ut kulekoden og innkapslere den i en separat Kule
klasse. La oss gjøre det.
Opprett en ny klasse som heter Kule
, utvide Sprite
klasse. Grunnkoden for denne klassen skal være:
pakke import flash.display.Sprite; offentlig klasse Bullet utvider Sprite offentlig funksjon Bullet ()
Deretter setter vi koden for å tegne kuleteksten, hentet fra Hoved
, i Kule
. Som vi gjorde med turret
klasse, oppretter vi en funksjon som heter tegne
i Kule
klasse:
privat funksjonstegn (): void var g: Graphics = this.graphics; g.beginFill (0xEEEEEE); g.drawCircle (0, 0, 5); g.endFill ();
Og vi kaller denne funksjonen fra Kule
konstruktør:
offentlig funksjon Bullet () draw ();
Nå legger vi til noen egenskaper til kulen. Legg til fire variabler: hastighet
, speed_x
, speed_y
og skader
, før Kule
konstruktør:
privat var hastighet: tall; privat var speed_x: Number; privat var speed_y: tall; offentlig var skade: int;
Hva er disse variablene for?
hastighet
: Denne variabelen lagrer kulehastigheten.speed_x
og speed_y
: Disse lagrer henholdsvis x- og y-komponentene av hastigheten, slik at beregningen av å bryte hastigheten til komponentene ikke må gjøres igjen og igjen. skader
: Dette er mengden skade kulen kan gjøre mot en fiende. Vi holder denne variabelen offentlig, da vi vil kreve dette i vår spillsløyfe i Hoved
klasse. Vi initialiserer disse variablene i konstruktøren. Oppdater din Kule
konstruktør:
offentlig funksjon Bullet (vinkel: tall) speed = 5; skade = 1; speed_x = Math.cos (vinkel * Math.PI / 180) * hastighet; speed_y = Math.sin (vinkel * Math.PI / 180) * hastighet; tegne();
Legg merke til vinkel
variabel vi mottar i konstruktøren. Dette er retningen (i grader) der kulen vil bevege seg. Vi bryter bare hastighet
inn i sine x og y komponenter og lagre dem for fremtidig bruk.
Det siste som gjenstår i Kule
klassen er å ha en Oppdater
funksjon som vil bli kalt fra spillsløyfen for å oppdatere (flytte) kulen. Legg til følgende funksjon på slutten av Kule
klasse:
offentlig funksjon oppdatering (): void x + = speed_x; y + = speed_y;
Bingo! Vi er ferdige med vår Kule
klasse.
Vi flyttet mye kulekode fra Hoved
klasse for seg selv Kule
klasse, så mye kode forblir ubrukt i Hoved
og mye må oppdateres.
Først sletter du createBullet ()
og moveBullet ()
funksjoner. Fjern også bullet_speed
variabel.
Deretter går du til skyte
funksjonen og oppdatere den med følgende kode:
privat funksjonsspor (e: MouseEvent): tomrom 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 + Math.sin (turret.rotation * Math.PI / 180) * 25; addChild (new_bullet);
Vi bruker ikke lenger createBullet
funksjon for å skape kule, bruk heller Kule
konstruktør og passere tårnet rotasjon
til det som er retningen for kulens bevegelse, og så trenger vi ikke å lagre den i kulen rotasjon
eiendom som vi gjorde tidligere. Også vi legger ikke noen lytter til kulen da kulen vil bli oppdatert fra spillsløyfen neste.
Nå som vi trenger å oppdatere kulene fra spillsløyfen, trenger vi en referanse om at de skal lagres et sted. Løsningen er den samme som for tårnene: opprett en ny Array
oppkalt kuler
og skyv kulene på den som de er opprettet.
Først erklærer du en matrise like under tårn
array-erklæring:
privat var ghost_turret: Turret; private vartårn: Array = []; private var kuler: Array = [];
Nå for å fylle denne gruppen. Vi gjør det når vi lager en ny kule - så i skyte
funksjon. Legg til følgende like før du legger til punktet:
var new_bullet: Bullet = ny Bullet (turret.rotation); new_bullet.x = turret.x + Math.cos (turret.rotation * Math.PI / 180) * 25; new_bullet.y = turret.y + Math.sin (turret.rotation * Math.PI / 180) * 25; bullets.push (new_bullet); addChild (new_bullet);
Akkurat som hvordan vi oppdaterer tårnene i spillsløyfen, vil vi også oppdatere kulene. Men denne gangen, i stedet for å bruke a for hver
loop, vi bruker en grunnleggende til
sløyfe. Før dette må vi legge til to variabler til toppen av spillsløyfen, slik at vi vet hvilke variabler som brukes i spillsløyfen, og kan sette dem fri for søppelsamling.
var turret: Turret; var bullet: Bullet;
Gå videre og legg til følgende kode i slutten av spillsløyfen:
for (var jeg: int = kuler. lengde - 1; i> = 0; i--) bullet = kuler [i]; hvis (! bullet) fortsetter; bullet.update ();
Her krysser vi over alle kulene på scenen hver ramme og ringer deres Oppdater
funksjon som gjør at de beveger seg. Vær oppmerksom på at vi gjentar det kuler
array i omvendt. Hvorfor? Vi ser dette fremover.
Nå som vi har a turret
variabel deklarert utenfor allerede, trenger vi ikke å deklarere det igjen inne i for hver
loop av tårn. Endre det til:
for hver (turret i tårnene) turret.update ();
Til slutt legger vi til grensekontrolltilstanden; Dette var tidligere i kulen ENTER_FRAME
men nå sjekker vi det i spillsløyfen:
hvis (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) bullets.splice (jeg, 1); bullet.parent.removeChild (bullet); Fortsette;
Vi kontrollerer om kulen er ute av scenens grense, og hvis så fjerner vi først sin referanse fra kuler
array ved hjelp av skjøt
funksjon, og fjern deretter kulen fra scenen og fortsett med neste iterasjon. Slik ser spillløkken ut:
privat funksjon gameLoop (e: Event): void var turret: Turret; var bullet: Bullet; for hver (turret i tårnene) turret.update (); for (var i: int = kuler.length - 1; i> = 0; i--) bullet = kuler [i]; hvis (! bullet) fortsetter; bullet.update ();
Hvis du nå kjører spillet, bør du ha samme funksjonalitet som i del 1, med kode som er mye mer ren og organisert.
Nå legger vi til et av de viktigste elementene i spillet: fienden. Første ting er å opprette en ny klasse som heter Fiende
utvide Sprite
klasse:
pakke import flash.display.Sprite; offentlig klasse Enemy utvider Sprite offentlig funksjon Enemy ()
Nå legger vi noen egenskaper til klassen. Legg til dem før din Fiende
konstruktør:
privat var speed_x: Number; privat var speed_y: tall;
Vi initialiserer disse variablene i Fiende
konstruktør:
offentlig funksjon Enemy () speed_x = -1.5; speed_y = 0;
Deretter lager vi tegne
og Oppdater
funksjoner for Fiende
klasse. Disse er svært lik dem fra Kule
. Legg til følgende kode:
privat funksjonstegn (): void var g: Graphics = this.graphics; g.beginFill (0xff3333); g.drawCircle (0, 0, 15); g.endFill (); offentlig funksjon oppdatering (): void x + = speed_x; y + = speed_y;
I vårt spill må vi ha mange hendelser som finner sted på bestemte tidspunkter eller gjentatte ganger med bestemte intervaller. Slike timing kan oppnås ved bruk av en tidsteller. Telleren er bare en variabel som økes etter hvert som tiden går i spillet. Det viktige her er når og av hvor mye beløp som skal øke telleren. Det er to måter der timing generelt er gjort i spill: Tidsbasert og Rammebasert.
Forskjellen er at enheten av trinn i tidsbasert spill er basert på sanntid (det vil si antall millisekunder som er gått), men i et rammebasert spill er stedsenheten basert på rammeenheter (dvs. antall rammer som er gått).
For vårt spill skal vi bruke en rammebasert teller. Vi har en teller som vi øker med en i spillsløyfen, som kjører hver ramme, og det vil i utgangspunktet gi oss antall rammer som har gått siden spillet startet. Gå videre og erklære en variabel etter de andre variabeldeklarasjonene i Hoved
klasse:
privat var ghost_turret: Turret; private vartårn: Array = []; private var kuler: Array = []; privat var global_time: tall = 0;
Vi øker denne variabelen i spillsløyfen øverst:
global_time ++;
Nå basert på denne telleren kan vi gjøre ting som å skape fiender, som vi vil gjøre neste.
Det vi vil gjøre nå, er å lage fiender på banen etter hvert to sekunder. Men vi har å gjøre med rammer her, husk? Så etter hvor mange rammer skal vi skape fiender? Vel, vårt spill kjører på 30 FPS, og øker dermed global_time
teller 30 ganger hvert sekund. En enkel beregning forteller oss at 3 sekunder = 90 rammer.
På slutten av spillsløyfen legger du til følgende hvis
blokkere:
hvis (global_time% 90 == 0)
Hva er den tilstanden om? Vi bruker modulo (%) operatøren, som gir resten av en divisjon - så global_time% 90
gir oss resten når global_time
er delt med 90
. Vi sjekker om resten er 0
, som dette vil bare være tilfelle når global_time
er et flertall av 90
- det vil si at tilstanden kommer tilbake ekte
når global_time
er lik 0
, 90
, 180
og så videre ... På denne måten oppnår vi en utløser hver 90 eller 3 sekunder.
Før vi lager fienden, erklærer vi en annen gruppe som heter fiender
like under tårn
og kuler
array. Dette vil bli brukt til å lagre referanser til fiender på scenen.
privat var ghost_turret: Turret; private vartårn: Array = []; private var kuler: Array = []; private var fiender: Array = []; privat var global_time: tall = 0;
Erklære også en fiende
variabel øverst på spillsløyfen:
global_time ++; var turret: Turret; var bullet: Bullet; var fiende: Fiende;
Til slutt legg til følgende kode inne i hvis
blokkere vi opprettet tidligere:
fiende = ny fiende (); fiende.x = 410; enemy.y = 30 + Math.random () * 370; enemies.push (fiende); addChild (fiende);
Her lager vi en ny fiende, plasserer den tilfeldig på høyre side av scenen, skyver den i fiender
array og legg det til scenen.
Akkurat som vi oppdaterer kulene i spillsløyfen, oppdaterer vi fiender. Sett følgende kode under tårnet for hver
løkke:
for (var j: int = enemies.length - 1; j> = 0; j--) fiende = fiender [j]; enemy.update (); hvis (fiende.x < 0) enemies.splice(j, 1); enemy.parent.removeChild(enemy); continue;
På samme måte som vi gjorde en grensekontroll for kuler, sjekker vi også på fiender. Men for fiender kontrollerer vi bare om de gikk ut av venstre side av scenen, da de bare beveger seg rett til venstre. Du bør se fiender kommer fra høyre hvis du kjører spillet nå.
Hver fiende har noe liv / helse, og det vil også vår. Vi vil også vise den gjenværende helsen på fiender. Kan deklarere noen variabler i Fiende
klasse for helse ting:
privat var health_txt: TextField; privat var helse: int; privat var speed_x: Number; privat var speed_y: tall;
Vi initialiserer Helse
variabel i konstruktøren neste. Legg til følgende i Fiende
konstruktør:
helse = 2;
Nå initialiserer vi hivtekstvariabelen til å vise på sentrum av fienden. Vi gjør det i tegne
funksjon:
health_txt = nytt 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 Tekstfelt
, sett fargen sin, plasser den og sett teksten til gjeldende verdi av Helse
Til slutt legger vi til en funksjon for å oppdatere fiendens helse:
offentlig funksjon oppdateringHelse (mengde: int): int helse + = mengde; health_txt.text = helse + ""; returnere helse;
Funksjonen aksepterer et heltall for å legge til helsen, oppdaterer helseteksten, og returnerer den endelige helsen. Vi kaller denne funksjonen fra vår spillsløyfe for å oppdatere hver fiendens helse og oppdage om den fortsatt er i live.
Først kan vi endre vår skyte
fungere litt. Erstatt eksisterende skyte
fungere med følgende:
privat funksjon skyte (turret: Turret, fiende: Enemy): void varvinkel: Nummer = Math.atan2 (fiende.y - turret.y, fiende.x - turret.x) / Math.PI * 180; turret.rotasjon = vinkel; var new_bullet: Bullet = ny Bullet (vinkel); new_bullet.x = turret.x + Math.cos (turret.rotation * Math.PI / 180) * 25; new_bullet.y = turret.y + Math.sin (turret.rotation * Math.PI / 180) * 25; bullets.push (new_bullet); addChild (new_bullet);
De skyte
funksjonen aksepterer nå to parametere. Den første er en referanse til et tårn som vil gjøre skytingen; den andre er en referanse til en fiende mot hvilken den vil skyte.
Den nye koden her ligner den som er til stede i turret
klassens Oppdater
funksjon, men i stedet for musens posisjon bruker vi nå fiendens cordinates. Så nå kan du fjerne all koden fra Oppdater
funksjon av turret
klasse.
Nå hvordan får man tårnene til å skyte mot fiender? Vel logikken er enkel for vårt spill. Vi gjør alle tårnene skyte den første fienden i fiender
array. Hva? La oss sette noen kode og deretter prøve å forstå. Legg opp følgende linjer i slutten av for hver
sløyfe som brukes til å oppdatere tårnene:
for hver (turret i tårnene) turret.update (); for hver (fiende i fiender) skyte (tårn, fiende); gå i stykker;
For hver turret oppdaterer vi nå den, og deretter er det igjen fiender
array, skyte den første fienden i gruppen og bryte fra løkken. Så i det vesentlige skyter hvert tårn den tidligste opprettede fienden som den alltid er i begynnelsen av matrisen. Prøv å kjøre spillet og du bør se tårn som skyter fiender.
Men vent, hva er den kule strømmen flyter? Ser ut som de skyter for fort. Kan se hvorfor.
Som vi vet går spillsløyfen hver ramme, det vil si 30 ganger i sekundet, slik at skytingserklæringen vi legger til i forrige trinn, blir kalt på hastigheten på vår spillsløyfe, og dermed ser vi en strøm av kuler som flyter. Ser ut som vi trenger en tidsplanmekanisme inne i tårnene også. Bytt til turret
klasse og legg til følgende kode:
privat var local_time: tall = 0; privat var reload_time: int;
lokal tid
: Våre teller er kalt lokal tid
i motsetning til global_time
i Hoved
klasse. Dette er av to grunner: først fordi denne variabelen er lokal til turret
klasse; For det andre fordi det ikke alltid går frem som vår global_time
variabel - den vil nullstille mange ganger i løpet av spillet. reload_time
: Dette er tiden som tårnet trenger for å laste på igjen etter å ha tatt et kule. I utgangspunktet er det tidsforskjellen mellom to punktskudd med et tårn. Husk at alle tidsenheter i vårt spill er i form av rammer. Øke lokal tid
variabel i Oppdater
funksjon og initialiser reload_time
i konstruktøren:
offentlig funksjon oppdatering (): void local_time ++;
offentlig funksjon Turret () reload_time = 30; tegne();
Deretter legger du til følgende to funksjoner på slutten av turret
klasse:
offentlig funksjon erReady (): Boolean return local_time> reload_time; tilbakestilling av offentlig funksjon (): void local_time = 0;
er klar
returnerer sant bare når gjeldende lokal tid
er større enn reload_time
, det vil si når tårnet har lastet på nytt. Og tilbakestille
funksjonen tilbakestilles ganske enkelt lokal tid
variabel, for å starte den på nytt.
Nå tilbake i Hoved
klassen, endre skytekoden i spillsløyfen vi la til i forrige trinn til følgende:
for hver (turret i tårnene) turret.update (); hvis (! turret.isReady ()) fortsetter; for hver (fiende i fiender) skyte (tårn, fiende); turret.reset (); gå i stykker;
Så hvis tårnet ikke er klart nå (er klar()
avkastning falsk
), fortsetter vi med neste iterasjon av turretløkken. Du vil se at tårnene brenner i et intervall på 30 bilder eller 1 sekund nå. Kul!
Fortsatt noe ikke riktig. Tårnene skyter mot fiender, uavhengig av avstanden mellom dem. Det som mangler her er område av et tårn. Hvert tårn bør ha sitt eget utvalg innenfor som det kan skyte en fiende. Legg til en annen variabel til turret
klassen kalles område
og sett den til 120
inne i konstruktøren:
privat var reload_time: int; privat var local_time: tall = 0; privat var utvalg: int;
offentlig funksjon Turret () reload_time = 30; område = 120; tegne();
Legg også til en funksjon som heter canShoot
på slutten av klassen:
offentlig funksjon canShoot (fiende: fiende): boolsk var dx: tall = fiende.x - x; var dy: Nummer = fiende.y - y; hvis (Math.sqrt (dx * dx + dy * dy) <= range) return true; else return false;
Hver tårn kan bare skyte en fiende når den oppfyller visse kriterier - for eksempel kan du la turret skyte bare røde fiender med mindre enn halvparten av livet og ikke mer enn 30 px unna. All slik logikk for å avgjøre om tårnet er i stand til å skyte en fiende eller ikke, vil gå inn i canShoot
funksjon, som returnerer ekte
eller falsk
i henhold til logikken.
Vår logikk er enkel. Hvis fienden er innenfor rekkevidde retur ekte
; ellers returnere falsk. Så når avstanden mellom tårnet og fienden (Math.sqrt (dx * dx + dy * dy)
) er mindre enn eller lik område
, det kommer tilbake ekte
. Litt mer endring i skyteseksjonen av spillsløyfen:
for hver (turret i tårnene) turret.update (); hvis (! turret.isReady ()) fortsetter; for hver (fiende i fiender) hvis (turret.canShoot (fiende)) skyte (tårn, fiende); turret.reset (); gå i stykker;
Nå bare hvis fienden er innenfor tårnet, vil tårnet skyte.
En svært viktig del av hvert spill er kollisjonsdeteksjonen. I vårt spill kollisjonskontroll gjøres mellom kuler og fiender. Vi legger til kollisjonsdeteksjonskoden inne i for hver
loop som oppdaterer kulene i spillsløyfen.
Logikken er enkel. For hver kule vi krysser fiender
array og sjekk om det er en kollisjon mellom dem. I så fall fjerner vi kulen, oppdaterer fiendens helse og bryter ut av løkken for å sjekke andre fiender. La oss legge til en kode:
for (i = bullets.length - 1; i> = 0; i--) bullet = bullets [i]; // Hvis kulen ikke er definert, fortsett med neste iterasjon hvis (! bullet) fortsetter; bullet.update (); hvis (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) bullets.splice (jeg, 1); bullet.parent.removeChild (bullet); Fortsette; for (var k: int = enemies.length - 1; k> = 0; k--) fiende = fiender [k]; hvis (bullet.hitTestObject (fiende)) bullets.splice (jeg, 1); bullet.parent.removeChild (bullet); hvis (fiende.updateHealth (-1) == 0) enemies.splice (k, 1); enemy.parent.removeChild (fiende); gå i stykker;
Vi bruker ActionScript hitTestObject
funksjon for å sjekke for kollisjon mellom kulen og fienden. Hvis kollisjonen oppstår, blir kula fjernet på samme måte som når den forlater scenen. Fiendens helse blir da oppdatert ved hjelp av updateHealth
metode, som kule
's skader
eiendommen er bestått. Hvis updateHealth
funksjonen returnerer et helt tall mindre enn eller lik 0
, Dette betyr at fienden er død og så fjerner vi den på samme måte som kulen.
Og vår kollisjon gjenkjenning er gjort!
Husk at vi krysser fiender og kuler omvendt i vår spillsløyfe. La oss forstå hvorfor. La oss anta at vi brukte en stigende til
sløyfe. Vi er på indeksen i = 3
og vi fjerner en kule fra arrayet. Ved fjerning av varen på posisjon 3
, dens plass er fylt av elementet da på posisjon 4
. Så nå varen tidligere på posisjon 4
er på 3
. Etter iterasjonen Jeg
øker med 1
og blir 4
og så gjenstand på posisjon 4
er sjekket.
Hopp, ser du hva som skjedde akkurat nå? Vi savnet bare varen nå på posisjon 3
som skiftet tilbake som følge av spleising. Og så bruker vi en omvendt til
sløyfe som fjerner dette problemet. Du kan se hvorfor.
La oss legge til noen ekstra ting for å få spillet til å se bra ut. Vi legger til funksjonalitet for å vise et tårnspekter når musen er svevet på den. Bytt til turret
klasse og legg til noen variabler til det:
privat var utvalg: int; privat var reload_time: int; privat var local_time: tall = 0; privat var kropp: Sprite; private var range_circle: Sprite;
Neste oppdatering av tegne
funksjon til følgende:
privat funksjonstegn (): void range_circle = new Sprite (); g = range_circle.graphics; g.beginFill (0x00D700); g.drawCircle (0, 0, område); g.endFill (); range_circle.alpha = 0.2; range_circle.visible = false; addChild (range_circle); body = new Sprite (); var g: Graphics = body.graphics; g.beginFill (0xD7D700); g.drawCircle (0, 0, 20); g.beginFill (0x800000); g.drawRect (0, -5, 25, 10); g.endFill (); addChild (legeme);
Vi bryter tårnens grafikk inn i to deler: kroppen og rekkeviddegrafen. Vi gjør dette for å bestille på de forskjellige delene av tårnet. Her krever vi range_circle
å ligge bak tårnets kropp, og så legger vi først til scenen. Til slutt legger vi til to muselyttere for å veksle rekkeviddegrafen:
privat funksjon onMouseOver (e: MouseEvent): void range_circle.visible = true; privat funksjon onMouseOut (e: MouseEvent): void range_circle.visible = false;
Fest nå lytterne til de respektive hendelsene på slutten av konstruktøren:
body.addEventListener (MouseEvent.MOUSE_OVER, onMouseOver); body.addEventListener (MouseEvent.MOUSE_OUT, onMouseOut);
Hvis du kjører spillet og prøver å distribuere et tårn, vil du se en flimring når du svinger på plassholdere. Hvorfor det?
Husk at vi setter mouseEnabled
egenskapen til spøkelseturret til falsk
? Vi gjorde det fordi, spøkelseturret var å fange musebegivenheter ved å komme inn mellom musen og stedholderen. Den samme situasjonen har kommet igjen da tårnet selv har to barn nå - sin kropp og rekkevidde sprite - som fanger musen hendelsene i mellom.
Løsningen er den samme. Vi kan sette deres individuelle mouseEnabled
egenskaper til falsk
. Men en bedre løsning er å sette spøkelseturret mouseChildren
eiendom til falsk
. Hva dette gjør er å begrense alle spøkelseturretens barn fra å motta museventyr. Ryddig, va? Gå videre og sett den til falsk
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);
Problemet løst.
Vi kan utvide denne demonstrasjonen for å inkludere mye mer avanserte funksjoner og gjøre det til et spillbart spill. Noen av disse kan være:
La oss se hva du kan komme med fra denne grunnleggende demo. Jeg vil gjerne høre om deg tårnforsvarsspill, og dine kommentarer eller forslag til serien.