Ehi, sviluppatori Flash, benvenuto alla seconda parte del mio tutorial sul gioco Tower Defense. Nella prima parte, abbiamo sviluppato il meccanismo di base per creare torrette e farle scattare verso il punto di click del mouse. Ma non è quello che sono le torrette! In questa parte estenderemo il gioco includendo i nemici, l'intelligenza artificiale di base (AI) nelle torrette e altri elementi di gioco. Siete pronti?
Questo è il gioco che stiamo per creare in questo tutorial:
Fai clic sui cerchi arancioni per posizionare le torrette. Le cerchie rosse sono nemiche e il numero su ciascuna rappresenta i punti ferita.
Nel tutorial precedente abbiamo sviluppato un gioco con segnaposto per le torrette. Potremmo distribuire le torrette facendo clic su quei segnaposti e le torrette puntano al puntatore del mouse e sparano proiettili verso il punto in cui l'utente ha fatto clic.
Abbiamo finito con a Principale
classe che aveva il ciclo di gioco e la logica di gioco. A parte questo, abbiamo avuto il Torretta
classe che non aveva nulla se non il aggiornare
funzione che ha fatto ruotare la torretta.
In precedenza abbiamo creato i proiettili Principale
classe e allegato un ENTER_FRAME
ascoltatore per spostarlo. Il proiettile non aveva abbastanza proprietà in precedenza da considerarlo come una classe separata. Ma in un gioco del genere i proiettili possono avere molte varietà come velocità, danni e così via, quindi è una buona idea estrarre il codice del proiettile e incapsularlo in un altro proiettile
classe. Facciamolo.
Crea una nuova classe chiamata proiettile
, estendendo il folletto
classe. Il codice di base per questa classe dovrebbe essere:
pacchetto import flash.display.Sprite; Bullet classe pubblica estende Sprite Bullet funzione pubblica ()
Quindi inseriamo il codice per disegnare la grafica del proiettile, presa da Principale
, nel proiettile
. Come abbiamo fatto con Torretta
classe, creiamo una funzione chiamata disegnare
nel proiettile
classe:
private function draw (): void var g: Graphics = this.graphics; g.beginFill (0xEEEEEE); g.drawCircle (0, 0, 5); g.endFill ();
E chiamiamo questa funzione dal proiettile
costruttore:
funzione pubblica Bullet () draw ();
Ora aggiungiamo alcune proprietà al proiettile. Aggiungi quattro variabili: velocità
, speed_x
, speed_y
e danno
, prima di proiettile
costruttore:
velocità var privata: numero; private var speed_x: Number; private var speed_y: Number; danno pubblico var: int;
A cosa servono queste variabili?
velocità
: Questa variabile memorizza la velocità del proiettile.speed_x
e speed_y
: Memorizzano le componenti x e y della velocità, rispettivamente, in modo che il calcolo della rottura della velocità nei suoi componenti non debba essere ripetuto più volte. danno
: Questa è la quantità di danno che il proiettile può infliggere a un nemico. Manteniamo questa variabile pubblica come sarà necessario nel nostro ciclo di gioco nel Principale
classe. Inizializziamo queste variabili nel costruttore. Aggiorna il tuo proiettile
costruttore:
funzione pubblica Bullet (angle: Number) speed = 5; danno = 1; speed_x = Math.cos (angle * Math.PI / 180) * velocità; speed_y = Math.sin (angle * Math.PI / 180) * velocità; disegnare();
Notare il angolo
variabile che riceviamo nel costruttore. Questa è la direzione (in gradi) in cui si muoverà il proiettile. Abbiamo appena rotto il velocità
nei suoi componenti xey e li memorizza nella cache per un uso futuro.
L'ultima cosa che rimane nel proiettile
la classe è avere un aggiornare
funzione che verrà chiamata dal loop di gioco per aggiornare (spostare) il proiettile. Aggiungi la seguente funzione alla fine del proiettile
classe:
public function update (): void x + = speed_x; y + = speed_y;
Bingo! Abbiamo finito con il nostro proiettile
classe.
Abbiamo spostato un sacco di codice bullet da Principale
classe a sé stante proiettile
classe, quindi un sacco di codice rimane inutilizzato in Principale
e molto deve essere aggiornato.
Innanzitutto, elimina il createBullet ()
e moveBullet ()
funzioni. Rimuovere anche il velocità del proiettile
variabile.
Quindi, vai al sparare
funzione e aggiornarlo con il seguente codice:
sparatoria di funzioni private (e: MouseEvent): void per ciascuna (torretta var: torretta nelle torrette) 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);
Non usiamo più il createBullet
funzione per creare proiettili piuttosto usare il proiettile
costruttore e passare la torretta rotazione
ad esso che è la direzione del movimento del proiettile e quindi non abbiamo bisogno di memorizzarlo nel proiettile rotazione
proprietà come abbiamo fatto in precedenza. Inoltre, non assegniamo alcun ascoltatore al proiettile poiché il proiettile verrà aggiornato dal loop di gioco successivo.
Ora che abbiamo bisogno di aggiornare i proiettili dal ciclo di gioco, abbiamo bisogno di un riferimento di loro per essere memorizzati da qualche parte. La soluzione è la stessa delle torrette: creane una nuova schieramento
di nome proiettili
e spingere i proiettili su di esso mentre vengono creati.
Prima dichiarare un array appena sotto il torrette
dichiarazione dell'array:
private var ghost_turret: Turret; torrette private var: Array = []; pallottole private var: Array = [];
Ora per popolare questa matrice. Lo facciamo ogni volta che creiamo un nuovo proiettile - quindi, nel sparare
funzione. Aggiungi quanto segue prima di aggiungere il proiettile allo stage:
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; bullets.push (new_bullet); addChild (new_bullet);
Proprio come aggiorneremo le torrette nel ciclo di gioco, aggiorneremo anche i proiettili. Ma questa volta, invece di usare a per ciascuno
loop, useremo un basic per
ciclo continuo. Prima di questo, dobbiamo aggiungere due variabili nella parte superiore del ciclo di gioco, in modo da sapere quali variabili sono utilizzate all'interno del ciclo di gioco e possiamo renderle libere per la garbage collection.
var torretta: torretta; var bullet: Bullet;
Vai avanti e aggiungi il seguente codice alla fine del ciclo di gioco:
for (var i: int = bullets.length - 1; i> = 0; i--) bullet = bullet [i]; se (! bullet) continua; bullet.update ();
Qui attraversiamo tutti i proiettili sul palco ogni frame e chiamiamo i loro aggiornare
funzione che li fa muovere. Nota qui che iteriamo il proiettili
array al contrario. Perché? Lo vedremo in anticipo.
Ora che abbiamo un torretta
variabile dichiarata all'esterno, non è necessario dichiararla di nuovo all'interno di per ciascuno
ciclo di torrette. Modificalo per:
per ogni (torretta nelle torrette) turret.update ();
Infine aggiungiamo la condizione di controllo dei confini; questo era in precedenza nel proiettile ENTER_FRAME
ma ora lo controlliamo nel ciclo di gioco:
se (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) bullets.splice (i, 1); bullet.parent.removeChild (proiettile); Continua;
Controlliamo se il proiettile è fuori dal limite del palcoscenico e, in tal caso, prima rimuoviamo il suo riferimento dal proiettili
array usando il giuntura
funzione, quindi rimuovere il proiettile dallo stage e continuare con l'iterazione successiva. Ecco come dovrebbe apparire il tuo ciclo di gioco:
funzione privata gameLoop (e: Event): void var torretta: Turret; var bullet: Bullet; per ogni (torretta nelle torrette) turret.update (); for (var i: int = bullets.length - 1; i> = 0; i--) bullet = bullet [i]; se (! bullet) continua; bullet.update ();
Se ora esegui il gioco, dovresti avere le stesse funzionalità della Parte 1, con un codice molto più pulito e organizzato.
Ora aggiungiamo uno degli elementi più importanti del gioco: il nemico. La prima cosa è creare una nuova classe chiamata Nemico
estendendo il folletto
classe:
pacchetto import flash.display.Sprite; public class Enemy estende Sprite public function Enemy ()
Ora aggiungiamo alcune proprietà alla classe. Aggiungili prima del tuo Nemico
costruttore:
private var speed_x: Number; private var speed_y: Number;
Inizializziamo queste variabili nel Nemico
costruttore:
funzione pubblica Enemy () speed_x = -1.5; speed_y = 0;
Quindi creiamo il disegnare
e aggiornare
funzioni per il Nemico
classe. Questi sono molto simili a quelli di proiettile
. Aggiungi il seguente codice:
private function draw (): void var g: Graphics = this.graphics; g.beginFill (0xff3333); g.drawCircle (0, 0, 15); g.endFill (); public function update (): void x + = speed_x; y + = speed_y;
Nel nostro gioco abbiamo bisogno di avere molti eventi che si svolgono in determinati momenti o ripetutamente a determinati intervalli. Tale tempistica può essere raggiunta utilizzando un contatore del tempo. Il contatore è solo una variabile che viene incrementata con il passare del tempo nel gioco. La cosa importante qui è quando e da quanto ammontare per incrementare il contatore. Esistono due modi in cui il tempo viene generalmente eseguito nei giochi: basato sul tempo e basato sul frame.
La differenza è che l'unità del gioco basato sul passo nel tempo è basata sul tempo reale (cioè il numero di millisecondi passati), ma in un gioco basato su frame, l'unità di passo è basata su unità di frame (cioè il numero di frame passati).
Per il nostro gioco useremo un contatore basato su frame. Avremo un contatore che incrementeremo di uno nel ciclo di gioco, che esegue ogni fotogramma, quindi ci darà il numero di fotogrammi che sono passati dall'inizio del gioco. Vai avanti e dichiara una variabile dopo le altre dichiarazioni di variabili nel file Principale
classe:
private var ghost_turret: Turret; torrette private var: Array = []; pallottole private var: Array = []; private var global_time: Number = 0;
Aumentiamo questa variabile nel ciclo di gioco in alto:
global_time ++;
Ora basato su questo segnalino possiamo fare cose come creare nemici, cosa che faremo dopo.
Quello che vogliamo fare ora è creare nemici sul campo dopo ogni due secondi. Ma qui abbiamo a che fare con i frame, ricordi? Quindi dopo quanti fotogrammi dovremmo creare nemici? Bene, il nostro gioco funziona a 30 FPS, incrementando così il global_time
contrastare 30 volte al secondo. Un semplice calcolo ci dice che 3 secondi = 90 fotogrammi.
Alla fine del ciclo di gioco aggiungi quanto segue Se
bloccare:
if (global_time% 90 == 0)
Di cosa tratta questa condizione? Usiamo l'operatore modulo (%), che fornisce il resto di una divisione - così global_time% 90
ci dà il resto quando global_time
è diviso da 90
. Controlliamo se il resto è 0
, come questo sarà solo il caso in cui global_time
è un multiplo di 90
- cioè, la condizione ritorna vero
quando global_time
è uguale a 0
, 90
, 180
e così via ... In questo modo, otteniamo un trigger ogni 90 frame o 3 secondi.
Prima di creare il nemico, dichiara un altro array chiamato nemici
appena sotto il torrette
e proiettili
array. Questo sarà usato per memorizzare i riferimenti ai nemici sul palco.
private var ghost_turret: Turret; torrette private var: Array = []; pallottole private var: Array = []; nemici privati var: Array = []; private var global_time: Number = 0;
Dichiara anche un nemico
variabile nella parte superiore del ciclo di gioco:
global_time ++; var torretta: torretta; var bullet: Bullet; var nemico: nemico;
Infine aggiungi il seguente codice all'interno del Se
blocco che abbiamo creato in precedenza:
nemico = nuovo nemico (); enemy.x = 410; enemy.y = 30 + Math.random () * 370; enemies.push (nemico); addChild (nemico);
Qui creiamo un nuovo nemico, posizionalo casualmente alla destra del palco, spingilo dentro nemici
array e aggiungilo al palco.
Proprio come aggiorniamo i proiettili nel ciclo di gioco, aggiorniamo i nemici. Inserisci il seguente codice sotto la torretta per ciascuno
ciclo continuo:
per (var j: int = nemici.lunghezza - 1; j> = 0; j--) nemico = nemici [j]; enemy.update (); se (nemico.x < 0) enemies.splice(j, 1); enemy.parent.removeChild(enemy); continue;
Proprio come abbiamo fatto un controllo di confine per i proiettili, controlliamo anche i nemici. Ma per i nemici controlliamo solo se sono usciti dal lato sinistro del palco, poiché si muovono solo da destra a sinistra. Dovresti vedere i nemici provenienti da destra se corri il gioco ora.
Ogni nemico ha una vita / salute e anche il nostro. Mostreremo anche la salute rimanente sui nemici. Dichiariamo alcune variabili nel file Nemico
classe per la salute:
private var health_txt: TextField; private var health: int; private var speed_x: Number; private var speed_y: Number;
Inizializziamo il Salute
variabile nel costruttore successivo. Aggiungi il seguente al Nemico
costruttore:
salute = 2;
Ora inizializziamo la variabile del testo di salute da mostrare al centro del nemico. Lo facciamo nel disegnare
funzione:
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 = health + ""; addChild (health_txt);
Tutto ciò che facciamo è creare un nuovo Campo di testo
, imposta il suo colore, posizionalo e imposta il suo testo sul valore corrente di Salute
Infine aggiungiamo una funzione per aggiornare la salute del nemico:
funzione pubblica updateHealth (amount: int): int health + = amount; health_txt.text = health + ""; restituire la salute;
La funzione accetta un numero intero da aggiungere alla salute, aggiorna il testo di integrità e restituisce lo stato di integrità finale. Chiameremo questa funzione dal nostro ciclo di gioco per aggiornare la salute di ogni nemico e rilevare se è ancora vivo.
Prima di tutto, modifica il nostro sparare
funziona un po '. Sostituisci l'esistente sparare
funzione con il seguente:
tiro a funzioni private (torretta: torretta, nemico: nemico): void var angle: Number = Math.atan2 (enemy.y - torretta.y, enemy.x - torretta.x) / Math.PI * 180; turret.rotation = angle; var new_bullet: Bullet = new Bullet (angle); 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);
Il sparare
la funzione ora accetta due parametri. Il primo è un riferimento a una torretta che farà le riprese; il secondo è un riferimento a un nemico verso il quale sparerà.
Il nuovo codice qui è simile a quello presente nel Torretta
La classe di aggiornare
funzione, ma al posto della posizione del mouse ora usiamo le coordinate del nemico. Quindi ora puoi rimuovere tutto il codice dal aggiornare
funzione del Torretta
classe.
Ora come far sparare le torrette ai nemici? Bene, la logica è semplice per il nostro gioco. Facciamo sparare a tutte le torrette il primo nemico nel nemici
array. Che cosa? Mettiamo un po 'di codice e poi proviamo a capire. Aggiungi le seguenti righe alla fine del per ciascuno
ciclo utilizzato per aggiornare le torrette:
per ogni (torretta nelle torrette) turret.update (); per ciascuno (nemico nei nemici) spara (torretta, nemico); rompere;
Per ogni torretta ora lo aggiorniamo, quindi iteriamo il nemici
array, spara al primo nemico dell'array e interrompi il ciclo. Quindi, in sostanza, ogni torretta spara al primo nemico creato poiché è sempre all'inizio dell'array. Prova a correre e dovresti vedere le torrette che sparano ai nemici.
Ma aspetta, cos'è il flusso di proiettili che scorre? Sembra che stiano sparando troppo velocemente. Vediamo perché.
Come sappiamo, il ciclo di gioco esegue ogni frame, vale a dire 30 volte al secondo nel nostro caso, quindi la frase di tiro che abbiamo aggiunto nel passaggio precedente viene chiamata alla velocità del nostro ciclo di gioco e quindi vediamo un flusso di proiettili che scorre. Sembra che abbiamo bisogno di un meccanismo di temporizzazione anche all'interno delle torrette. Passa al Torretta
classe e aggiungi il seguente codice:
private var local_time: Number = 0; private var reload_time: int;
ora locale
: Il nostro contatore è chiamato ora locale
in contrasto con il global_time
nel Principale
classe. Questo è per due motivi: primo, perché questa variabile è locale al Torretta
classe; secondo, perché non va sempre avanti come il nostro global_time
variabile - si resetterà molte volte durante il corso del gioco. reload_time
: Questo è il tempo richiesto dalla torretta per ricaricare dopo aver sparato un proiettile. Fondamentalmente è la differenza di tempo tra due colpi di proiettile di una torretta. Ricorda tutte le unità del tempo nel nostro gioco sono in termini di frame. Incrementa il ora locale
variabile nel aggiornare
funzione e inizializza il reload_time
nel costruttore:
public function update (): void local_time ++;
funzione pubblica Turret () reload_time = 30; disegnare();
Quindi aggiungere le seguenti due funzioni alla fine del Torretta
classe:
public function isReady (): Boolean return local_time> reload_time; public function reset (): void local_time = 0;
è pronto
restituisce true solo quando corrente ora locale
è maggiore del reload_time
, cioè quando la torretta si è ricaricata. E il reset
la funzione semplicemente resetta il ora locale
variabile, per avviarlo di nuovo.
Ora di nuovo in Principale
classe, modifica il codice di ripresa nel loop di gioco che abbiamo aggiunto nel passaggio precedente al seguente:
per ogni (torretta nelle torrette) turret.update (); se (! turret.isReady ()) continua; per ciascuno (nemico nei nemici) spara (torretta, nemico); turret.reset (); rompere;
Quindi se ora la torretta non è pronta (è pronto()
ritorna falso
), continuiamo con la successiva iterazione del ciclo della torretta. Vedrai che le torrette sparano con un intervallo di 30 fotogrammi o 1 secondo ora. Freddo!
Ancora qualcosa non va bene. Le torrette sparano ai nemici indipendentemente dalla distanza tra loro. Quello che manca qui è il gamma di una torretta. Ogni torretta dovrebbe avere il proprio raggio all'interno del quale può sparare a un nemico. Aggiungi un'altra variabile al Torretta
classe chiamata gamma
e impostarlo 120
all'interno del costruttore:
private var reload_time: int; private var local_time: Number = 0; range var privato: int;
funzione pubblica Turret () reload_time = 30; intervallo = 120; disegnare();
Aggiungi anche una funzione chiamata canShoot
alla fine della classe:
public function canShoot (enemy: Enemy): Boolean var dx: Number = enemy.x - x; var dy: Number = enemy.y - y; if (Math.sqrt (dx * dx + dy * dy) <= range) return true; else return false;
Ogni torretta può sparare a un nemico solo quando soddisfa determinati criteri - ad esempio, puoi lasciare che la torretta spari solo nemici rossi con meno della metà della loro vita e non più di 30px di distanza. Tutta questa logica per determinare se la torretta è in grado di sparare a un nemico o no andrà nel canShoot
funzione, che restituisce vero
o falso
secondo la logica.
La nostra logica è semplice. Se il nemico è nel raggio di ritorno vero
; altrimenti restituisci falso. Quindi quando la distanza tra la torretta e il nemico (Math.sqrt (dx * dx + dy * dy)
) è inferiore o uguale a gamma
, ritorna vero
. Un po 'più di modifiche nella sezione shoot del loop di gioco:
per ogni (torretta nelle torrette) turret.update (); se (! turret.isReady ()) continua; per ciascuno (nemico nei nemici) if (torretta.canaiotto (nemico)) spara (torretta, nemico); turret.reset (); rompere;
Ora solo se il nemico si trova entro il raggio della torretta, la torretta scatterà.
Una parte molto importante di ogni gioco è il rilevamento delle collisioni. Nel nostro gioco il controllo della collisione avviene tra proiettili e nemici. Aggiungeremo il codice di rilevamento delle collisioni all'interno di per ciascuno
loop che aggiorna i proiettili nel loop di gioco.
La logica è semplice Per ogni proiettile attraversiamo il nemici
array e controllare se c'è una collisione tra loro. Se è così, rimuoviamo il proiettile, aggiorniamo la salute del nemico e scappiamo dal ciclo per controllare gli altri nemici. Aggiungiamo un po 'di codice:
for (i = bullets.length - 1; i> = 0; i--) bullet = bullet [i]; // se il punto non è definito, continuare con l'iterazione successiva se (! bullet) continua; bullet.update (); se (bullet.x < 0 || bullet.x > stage.stageWidth || bullet.y < 0 || bullet.y > stage.stageHeight) bullets.splice (i, 1); bullet.parent.removeChild (proiettile); Continua; per (var k: int = nemici.lunghezza - 1; k> = 0; k--) nemico = nemici [k]; if (bullet.hitTestObject (nemico)) bullets.splice (i, 1); bullet.parent.removeChild (proiettile); if (enemy.updateHealth (-1) == 0) enemy.splice (k, 1); enemy.parent.removeChild (nemico); rompere;
Usiamo ActionScript hitTestObject
funzione per verificare la collisione tra il proiettile e il nemico. Se si verifica la collisione, il proiettile viene rimosso allo stesso modo di quando lascia il palco. La salute del nemico viene quindi aggiornata usando il updateHealth
metodo, a cui proiettile
'S danno
la proprietà è passata. Se la updateHealth
la funzione restituisce un numero intero inferiore o uguale a 0
, questo significa che il nemico è morto e quindi lo rimuoviamo allo stesso modo del proiettile.
E il nostro rilevamento delle collisioni è fatto!
Ricorda che attraversiamo i nemici e i proiettili al contrario nel nostro ciclo di gioco. Capiamo perché. Supponiamo di aver usato un ascendente per
ciclo continuo. Siamo su indice i = 3
e rimuoviamo un proiettile dall'array. Sulla rimozione dell'articolo in posizione 3
, il suo spazio è riempito dall'elemento quindi in posizione 4
. Quindi ora l'articolo precedentemente in posizione 4
è a 3
. Dopo l'iterazione io
aumenta di 1
e diventa 4
e così oggetto in posizione 4
è controllato.
Oops, vedi cosa è successo proprio ora? Abbiamo appena perso l'oggetto ora in posizione 3
che si è spostato indietro come risultato dello splicing. E così usiamo un rovescio per
ciclo che rimuove questo problema. Puoi vedere perché.
Aggiungiamo alcune cose extra per rendere il gioco un bell'aspetto. Aggiungeremo funzionalità per visualizzare l'intervallo di una torretta quando il mouse viene posizionato su di esso. Passa al Torretta
classe e aggiungere alcune variabili ad esso:
range var privato: int; private var reload_time: int; private var local_time: Number = 0; corpo var privato: Sprite; private var range_circle: Sprite;
Prossimo aggiornamento del disegnare
funzione al seguente:
private function 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); 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 (corpo);
Rompiamo la grafica della torretta in due parti: il corpo e la grafica della gamma. Lo facciamo in modo da dare un ordine alle diverse parti della torretta. Qui richiediamo il range_circle
essere dietro il corpo della torretta, e così lo aggiungiamo prima al palco. Infine, aggiungiamo due listener del mouse per alternare la grafica dell'intervallo:
funzione privata onMouseOver (e: MouseEvent): void range_circle.visible = true; funzione privata onMouseOut (e: MouseEvent): void range_circle.visible = false;
Ora allega gli ascoltatori ai rispettivi eventi alla fine del costruttore:
body.addEventListener (MouseEvent.MOUSE_OVER, onMouseOver); body.addEventListener (MouseEvent.MOUSE_OUT, onMouseOut);
Se esegui il gioco e provi a schierare una torretta, vedrai uno sfarfallio quando tieni il mouse sui segnaposto. Perché?
Ricorda che abbiamo impostato il mouseEnabled
proprietà della torretta fantasma a falso
? L'abbiamo fatto perché, la torretta fantasma stava catturando gli eventi del mouse entrando tra il mouse e il segnaposto. La stessa situazione è arrivata ancora una volta dato che la torretta in sé ha due figli - il suo corpo e lo sprite della gamma - che stanno catturando gli eventi del mouse tra.
La soluzione è la stessa. Possiamo impostare il loro individuo mouseEnabled
proprietà a falso
. Ma una soluzione migliore è impostare la torretta fantasma mouseChildren
proprietà a falso
. Ciò che fa è limitare tutti i bambini della torretta fantasma dalla ricezione di eventi del mouse. Pulito, eh? Vai avanti e impostalo su falso
nel Principale
costruttore:
ghost_turret = new Turret (); ghost_turret.alpha = 0.5; ghost_turret.mouseEnabled = false; ghost_turret.mouseChildren = false; ghost_turret.visible = false; addChild (ghost_turret);
Problema risolto.
Potremmo estendere questa demo per includere funzionalità molto più avanzate e trasformarla in un gioco giocabile. Alcuni dei quali potrebbero essere:
Vediamo cosa puoi inventare da questa demo di base. Sarò felice di conoscere i tuoi giochi di difesa della torre e i tuoi commenti o suggerimenti per la serie.