Ricerca del Percorso Basato su Griglia
In questo tutorial, realizzeremo una simulazione di ricerca del percorso basata su una griglia di array bidimensionale. Questo ci darà l'idea di base per creare attività di ricerca del percorso nei nostri giochi. Visualizzeremo la griglia utilizzando oggetti quadrati vuoti come piastrelle e un oggetto rotondo come il nostro avatar che può muoversi in quell'area della griglia con il nostro comando.
I. Impostazione degli oggetti
Utilizzeremo solo quattro oggetti nel nostro progetto. Il nostro avatar verde, una piastrella blu, un blocco bianco e l'etichetta della griglia per impostare e visualizzare la nostra griglia.
Avatar
Il nostro avatar è un oggetto vuoto che ha una scala x e y del 50%. Imposta la sua collisione su una forma rotonda in modo che appaia come quello nell'immagine sottostante. Questo oggetto avrà tre attributi predefiniti: su piastrella, piastrella precedente e piastrella target. Imposta i valori predefiniti di questi attributi a zero in modo che non abbiano un valore nullo quando cercheremo di recuperarli in seguito.
Oggetto Piastrella
Crea un altro oggetto vuoto che sarà utilizzato per visualizzare le piastrelle nella nostra griglia. Anche la sua scala è del 50% e ha solo un attributo predefinito: su piastrella. Imposta anche questo valore a zero.
Oggetto Blocco
Crea un altro oggetto vuoto che servirà come blocchi nella nostra griglia. Questo è un oggetto vuoto bianco con una scala del 40%. Il nostro avatar non potrà attraversare una piastrella su cui c'è un blocco.
Etichetta della Griglia
Questa è solo un'etichetta che avrà i comportamenti che permetteranno di impostare e visualizzare la nostra griglia. Ha attributi predefiniti: start x con un valore di 4 e start y con un valore di 3. Questi valori sono offset che saranno utilizzati come riferimento quando genereremo le nostre piastrelle per posizionare la nostra griglia ordinatamente al centro.
Avatar/Piastrella Attributi predefiniti:
Definiamo una piastrella qui come un array di dimensione 2 che avrà un valore x e y basato sulla nostra griglia.
- su piastrella - questo è il valore della piastrella su cui si trova attualmente il nostro oggetto nella nostra griglia
- piastrella precedente - una piastrella che è stata precedentemente attraversata dal nostro avatar
- piastrella target - la piastrella a cui il nostro avatar si dirigerà
II. Impostazione della griglia
All'interno dell'etichetta della griglia è dove definiremo il nostro array 2D e il rilascio della nostra griglia. Ci sono 2 punti chiave principali in questo oggetto: impostare l'array e visualizzare l'array. Cominciamo con il bundle di impostazione dell'array.
Imposta l'array - bundle
Per prima cosa, creare un array vuoto chiamato 'Grid'. Questo array conterrà il nostro array bidimensionale. Avremo un contenitore box chiamato 'x row count' che avrà un valore di 24 e un altro array vuoto chiamato 'y row' che avrà 18 valori vuoti.
Il primo comportamento nel nostro bundle è un ciclo con un numero di ripetizioni di 'x row count'. Per ogni passo di questo ciclo, aggiungeremo una riga y vuota all'array 'Grid'. Questo creerà un array all'interno di un array con una dimensione di 24x18.
Nota che abbiamo collegato un commento inattivo all'inizio del nostro bundle per negare l'esecuzione automatica di questo comportamento radice. Un comportamento radice è un comportamento che non si attiva in base a nessun evento e viene posizionato apertamente nell'interfaccia.
Visualizza la griglia - bundle
La cosa principale che faremo qui è esplorare ogni valore del nostro 'Grid array' e generare un oggetto piastrella. Aggiungeremo anche una condizione nel nostro ciclo che consentirà la generazione di un blocco bianco sopra l'oggetto piastrella.
Innanzitutto, ottieni il conteggio degli array della nostra array 'y row', il valore dell'attributo 'start x' di questo oggetto e il 'start y'.
Crea un ciclo che ha una ripetizione di 'x row count' e per ogni passo di questo ciclo, aggiungeremo il valore dell'indice di quel ciclo e il valore dell'attributo 'start x'. Questo porta a una posizione x assoluta che utilizzeremo per posizionare le nostre piastrelle generate in seguito. Il passo successivo è il 'ciclo y row' che ha una ripetizione di 'y row count'. Per ogni passo di questo ciclo, aggiungeremo il valore dell'indice di quel ciclo e il valore dell'attributo 'start y', che ora porterà alla posizione y assoluta.
Dopo aver aggiunto i valori sotto il 'ciclo y row', dobbiamo generare l'oggetto blu. Imposta il numero di oggetti vivi a 999 perché ne avremo bisogno di molti per la nostra griglia e anche con una durata di 0. Quindi sposta l'oggetto generato a un punto x con un valore dal ciclo x 'aggiungi valori', e il punto y con valore dal ciclo y 'aggiungi valori'.
Il passo successivo è aggiungere un array con 2 valori vuoti chiamato 'On tile' che utilizzeremo solo come segnaposto per l'array. Dopo aver spostato l'oggetto piastrella dobbiamo modificare l'array 'On tile' sostituendo il suo valore all'indice 0 con il valore del 'ciclo y row loop'. Quindi aggiungi un'altra modifica all'array che sostituisce il valore all'indice 1 con l'indice del ciclo y. Queste sono le coordinate x e y della nostra griglia che l'oggetto avrà come attributo 'on tile'.
Ora, imposta l'attributo dell'oggetto generato con una chiave dinamica, 'on tile', e con un valore di 'On tile - array'.
Sempre, sotto il ciclo y row, c'è la condizione di generare l'oggetto blocco bianco. Avremo una probabilità di 2 su 5 di eseguire questo bundle che aggiungerà alla randomizzazione della nostra griglia. Quindi contrassegneremo un valore di 1 alle coordinate x e y in questo nostro array 'Grid' che ci dice che quella coordinata ha un blocco generato sopra di essa.
Per prima cosa, ottieni un numero casuale compreso tra 1 e 5. Se quel numero è minore o uguale a 2, genereremo il blocco. Imposta il numero di oggetti vivi a 999 e sposta quell'oggetto nello stesso punto della piastrella blu che abbiamo generato in precedenza, anche con una durata di 0.
Successivamente, memorizziamo le informazioni che questa coordinata era occupata da un blocco, se è stata generata. Lo facciamo contrassegnando quella coordinata con un valore di 1. Per prima cosa, ottieni il valore all'indice 'x row loop' dell'array 'Grid'. Questo valore ci darà un array di una 'y row'. Modificheremo questa 'y row' sostituendo il suo valore all'indice 'y row loop' con il valore 1, che è il valore contrassegnato. Poiché questa modifica del valore si applica solo a quel valore, e non a 'Grid' stesso, dobbiamo ancora modificare l'array 'Grid'. Sostituisci il valore all'indice 'x row loop' dell'array 'Grid' con un valore di 'modify y row - array'.
Una volta eseguito, dovrebbe risultare in questo tipo di forma.
III. Al Tocco sulla Piastrella
Per interagire con la griglia stessa, avremo bisogno di un comportamento bundle ogni volta che premiamo una piastrella blu. La prima pressione porterà all'apparizione del nostro avatar nella nostra griglia, e qualsiasi pressione successiva dopo quell'evento inizierà la sua ricerca del percorso.
All'interno dell'oggetto blu c'è un bundle di comportamenti che ha 3 punti principali: resettare la piastrella precedente del nostro avatar, impostare la sua piastrella attuale/impostare la sua piastrella target, quindi impostare un'animazione di colore per visualizzare l'evento di tocco sullo schermo.
Per prima cosa, ottieni l'attributo 'on tile' dell'oggetto piastrella. Imposta l'attributo 'previous tile' del nostro avatar a 0. Il nostro avatar sarà impostato per evitare di tornare a una "piastrella precedente", quindi resettiamo la "piastrella precedente" ad ogni pressione della piastrella.
Successivamente, ottieni l'attributo 'on tile' del nostro avatar. La prima condizione if è se il valore 'on tile' è uguale a zero. Questo significa che se l'avatar non è ancora apparso, allora questo risulterà vero. Se è vero, impostiamo il suo attributo 'on tile' con un valore dell'attributo 'on tile' dell'oggetto piastrella. Quindi sposta la posizione del nostro avatar prendendo la posizione dell'oggetto piastrella, puntando i suoi valori x e y a quel punto con una durata di 0.
Se il valore 'on tile' non è uguale a zero. imposteremo l'attributo 'target tile' del nostro avatar con il valore dell'attributo 'on tile' dell'oggetto piastrella. Questo significa che il nostro avatar è già nella nostra griglia, e quindi, possiamo eseguire il bundle di comportamento, 'trova il percorso'. Non abbiamo ancora questo comportamento ma lo sistemeremo di nuovo dopo aver fatto la parte successiva di questo tutorial per il bundle 'trova il percorso'.
Ora che abbiamo impostato correttamente il nostro avatar nella nostra griglia, dobbiamo solo visualizzare questo evento di pressione. Per prima cosa, creiamo un comportamento radice 'ottieni colore' per ottenere il suo colore originale. Poi dopo l'evento di pressione, impostiamo il colore dell'oggetto piastrella su nero con una durata di 0, quindi impostiamo di nuovo il suo colore al valore originale con una durata di 0.2.
Premere su una piastrella blu dovrebbe portare a questo.
IV. Esegui il Bundle Trova il Percorso
Per quest'ultima parte del nostro tutorial, faremo l'algoritmo che ci consente di trovare la piastrella più vicina che il nostro avatar può prendere per raggiungere la sua destinazione. Questo bundle verrà eseguito ripetutamente per ogni passo di piastrella che il nostro avatar muove sulla nostra griglia.
Imposteremo l'algoritmo all'interno del nostro oggetto avatar e avrà tre punti principali: trovare le piastrelle adiacenti, trovare la piastrella adiacente più vicina e il movimento verso quella piastrella adiacente.
Trovare le piastrelle adiacenti
In questa parte, raccoglieremo tutte le piastrelle adiacenti che il nostro avatar sarà in grado di attraversare. Controlliamo le sue quattro piastrelle adiacenti in direzione e vediamo se quelle piastrelle hanno un blocco sopra di esse o se sono state precedentemente calpestate.
Per prima cosa, aggiungi il nostro array 'Piastrelle Adiacenti'. Un array 'Direzione' con 2 valori vuoti e i quattro array direzionali che hanno 2 valori ciascuno: N (0,1), S (0,-1), E (1,0), W(-1,0).
Il primo comportamento nel nostro bundle è quello di cancellare le nostre piastrelle adiacenti. Poiché eseguiremo questo bundle ripetutamente, abbiamo bisogno di resettare le 'piastrelle adiacenti' raccolte ogni volta. I successivi quattro comportamenti sono modifiche all'array 'Direzione'. Impostiamo l'array dell'array 'Direzione' quattro volte con i quattro array direzionali, quindi eseguiamo il bundle sottostante. Lo facciamo per creare un ciclo con i diversi valori dell'array 'Direzione' ogni volta.
Ora che abbiamo la direzione, dobbiamo solo combinare i loro valori x e y con l'attributo 'on tile' del nostro avatar. Quindi saremo in grado di ottenere il valore target nell'array 'Grid' per sapere se quella piastrella era contrassegnata con un blocco.
'Direzione x' è il valore dell'array 'Direzione' all'indice 0, 'ottieni on tile' x è il valore di 'ottieni on tile' all'indice 0. Target x è la somma dei valori di 'direzione x' e 'ottieni on tile x'. Lo stesso vale per i valori y ma con un indice target di 1.
'Target y row' è il valore dell'array 'Grid' all'indice 'Target x'. E poi l'indice target in 'y row' sarà il valore dell'array 'Target y row' all'indice di 'Target y'. Questa è la coordinata nella nostra griglia che ci farà sapere se era contrassegnata con un blocco.
Se il valore in 'Target index in y row' è 1, allora quella piastrella target è stata contrassegnata come bloccata. Ma se il valore non è uguale a 1, allora possiamo continuare nel nostro bundle.
Poiché le nostre coordinate Target x e y hanno superato la nostra condizione, abbiamo aggiunto un nuovo array piastrella vuoto chiamato 'Nuova piastrella adiacente'. Questo memorizzerà i valori di Target x e y come un array di piastrella. Imposteremo il valore di Target x all'indice 0 di 'Nuova piastrella adiacente' e Target y al suo indice 1.
Ora ottieni l'attributo 'previous tile' del nostro avatar. Se 'previous tile' non è uguale alla 'nuova piastrella adiacente', ciò significherebbe che la nuova piastrella non è stata precedentemente attraversata. Quindi, possiamo aggiungere in sicurezza la 'Nuova Piastrella Adiacente' all'array 'Piastrelle Adiacenti' appending it. Imposteremo il valore di 'piastrella precedente' più tardi dopo aver spostato con successo il nostro avatar su un'altra piastrella.
"Puoi espandere questo bundle creando un array direzionale a 8 che consente al tuo avatar di muoversi anche in direzioni diagonali."
Trovare la piastrella adiacente più vicina
Ora che abbiamo raccolto le nostre piastrelle adiacenti affidabili, dobbiamo solo ottenere la piastrella adiacente che è più vicina alla piastrella target del nostro avatar. Eseguiremo il calcolo utilizzando una formula di distanza fornita dai valori x e y della nostra piastrella target e delle piastrelle adiacenti.
Ci sono due punti chiave in questo bundle: l'inizializzazione delle variabili per il calcolo e il calcolo delle distanze delle piastrelle all'interno di un ciclo.
a. Inizializzazione delle variabili
Per prima cosa otteniamo il conteggio dell'array delle piastrelle adiacenti. Quindi otteniamo l'attributo 'target tile' del nostro avatar e otteniamo i suoi valori x e y. Aggiungeremo 2 nuovi contenitori box: il 'Min distance' e l' 'Index di piastrella target'. Impostiamo il valore iniziale di 'Min distance' a 9999, e il valore dell' 'Index di piastrella target' a 0. La distanza minima è impostata a un numero elevato perché abbiamo bisogno della distanza minima dall'inizio. L'indice della piastrella target è il nostro indice di riferimento nell'array 'Piastrelle Adiacenti' che ha la distanza minore rispetto alla 'piastrella target'.
Il nostro obiettivo principale qui è ottenere l'indice della piastrella all'interno del nostro array 'Piastrelle Adiacenti' che è più vicino alla nostra 'piastrella target'.
b. Calcolo delle distanze delle piastrelle
In questo bundle, eseguiremo il calcolo all'interno di un ciclo che ripeteremo per ogni piastrella adiacente. Il ciclo si ripete secondo il 'conteggio delle piastrelle adiacenti' e otteniamo il valore di piastrella dell'array 'Piastrelle Adiacenti' utilizzando l'indice di quel ciclo.
Ottieni i valori x e y di quella piastrella adiacente e poi otterremo la distanza tra la nostra 'piastrella target' e la 'piastrella adiacente' usando questa formula:
distanza = sqrt((x2 - x1)^2+(y2 - y1)^2)
x1 = Target x
x2 = Adjacente x
y1 = Target y
y2 = Adjacente y
Per prima cosa, sottraiamo i loro valori x e y, moltiplichiamo per se stessi per ottenere i loro valori esponenziali, sommiamo quei valori, e quindi calcoliamo la radice quadrata dei valori sommati per ottenere il valore della distanza.
Se il valore della 'Distanza' è inferiore al valore della container box 'Min distance', imposteremo quindi il valore dell'indice della piastrella target sull'indice corrente del ciclo, che è l'indice della nostra piastrella recuperata all'interno dell'array 'Piastrelle Adiacenti'. Imposteremo anche il valore della container box 'Min distance' con il valore di 'Distanza' affinché possiamo confrontarlo con la piastrella successiva del nostro ciclo.
Dopo la fine del ciclo, abbiamo confrontato ognuna delle nostre piastrelle adiacenti e abbiamo ottenuto il valore dell'indice della piastrella adiacente che è più vicina alla nostra 'piastrella target'.
Movimento verso la piastrella adiacente
In questo ultimo bundle del nostro tutorial, muoveremo il nostro avatar alla piastrella adiacente più vicina e ripeteremo l'intero bundle 'Trova il Percorso' se non ci siamo già mossi verso la nostra 'piastrella target'.
La prima cosa è controllare se il nostro 'Conteggio delle piastrelle adiacenti' è maggiore di 0. Questo è per garantire che ci muoveremo solo se abbiamo recuperato almeno una piastrella adiacente affidabile.
Quindi 'Ottieni la piastrella più vicina' utilizzando il valore di 'Indice piastrella target' dal bundle precedente per ottenere il valore dell'array dell'array 'Piastrelle Adiacenti'.
Per ottenere il punto esatto in cui il nostro avatar si muoverà, avremo bisogno dei valori delle piastrelle x e y di quella piastrella, e anche dei valori degli attributi 'start x' e 'start y' della nostra etichetta 'Grid'. Aggiungiamo quindi il valore x della nostra 'piastrella più vicina' al valore 'start x', e anche per i valori y. Questi valori aggiunti sono i nostri punti x e y target dove il nostro avatar si muoverà.
Prima di muoverci verso quel punto, impostiamo il 'previous tile' del nostro avatar con il suo valore corrente dell'attributo 'on tile'. Possiamo ottenere questo valore 'on tile' dai bundle precedenti. Quindi muoviamo il nostro avatar verso i nostri punti target, con una durata di 0.2.
Al termine del comportamento 'Muovi verso punto', ora impostiamo il valore dell'attributo 'on tile' del nostro avatar con il valore dell'array 'Ottieni piastrella più vicina'. Se il valore dell'array 'Ottieni piastrella più vicina' non è uguale alla nostra 'piastrella target', ripeteremo quindi il bundle 'Trova il Percorso', dunque, ripetendo l'intero bundle di nuovo. Il valore dell'attributo 'piastrella target' può essere ottenuto dal bundle precedente.
Premendo su qualsiasi piastrella blu, e dopo l'apparizione del nostro avatar sulla griglia, il bundle 'Trova il Percorso' verrà eseguito. Questo innescherà il movimento dell'avatar da piastrella a piastrella.
Conclusione
In questo tutorial, abbiamo imparato a realizzare un'attività di ricerca del percorso per un oggetto utilizzando un array che abbiamo chiamato 'Grid', che viene utilizzato per memorizzare informazioni su se quella piastrella era occupata o meno. Puoi espandere questa idea, utilizzando gli id degli oggetti come archivio delle informazioni anziché solo un numero per il nostro array 'Grid'. Questo ci fornirà informazioni più affidabili che possiamo utilizzare quando facciamo ricerca del percorso. Ad esempio, possiamo ottenere gli attributi di quell'id oggetto per sapere se è vivo o meno, se ci permetterà di calpestare la sua piastrella o meno.
Questo tutorial ha solo servito a dare l'idea di base dietro la ricerca del percorso. Un aspetto negativo di questo è che non crea il percorso più breve possibile per una piastrella target, e controlla solo la sua piastrella adiacente attuale. Questo può portare a un ciclo di movimento che non raggiunge da nessuna parte.
Tuttavia, questo può essere risolto espandendo il nostro algoritmo di ricerca del percorso. Possiamo farlo reiterando sulle piastrelle adiacenti recuperate per ottenere anche le loro piastrelle adiacenti fino a trovare la nostra piastrella target. Ogni piastrella adiacente più vicina trovata sarà aggiunta a un elenco. Per evitare un ciclo infinito, aggiungi una condizione che, se quella piastrella adiacente è già stata controllata, quella piastrella non verrà aggiunta al nostro elenco. Inoltre, aggiungi un limite massimo sul conteggio delle iterazioni per prevenire un ciclo infinito causato dalla piastrella target se è troppo lontano o impossibile da trovare. Una volta che quell'iterazione trova la piastrella target, usciamo da quell'iterazione e iniziamo a muovere l'avatar da piastrella a piastrella utilizzando l'elenco delle piastrelle.

