Rasterbasierte Pfadsuche
In diesem Tutorial werden wir eine Pfadsimulationssituation basierend auf einem 2-dimensionalen Array-Raster erstellen. Dies wird uns die grundlegende Idee geben, um Pfadsuchaktivitäten für unsere Spiele zu erstellen. Wir werden das Raster mit leeren quadratischen Objekten als Kacheln und einem runden Objekt als unserem Avatar visualisieren, das sich in diesem Rasterbereich mit unserem Befehl bewegen kann.
I. Objekte einrichten
Wir verwenden nur vier Objekte in unserem Projekt. Unser grüner Avatar, eine blaue Kachel, eine weiße Blockade und das Rasteretikett zur Einrichtung und Visualisierung unseres Rasters.
Avatar
Unser Avatar ist ein leeres Objekt mit einem x- und y-Maßstab von 50%. Stellen Sie seine Kollision auf eine runde Form ein, damit es wie das Bild unten aussieht. Dieses Objekt wird drei vordefinierte Attribute haben: „auf Kachel“, „vorherige Kachel“ und „Zielkachel“. Setzen Sie die Standardwerte dieser Attribute auf null, damit sie später keinen Nullwert haben, wenn wir versuchen, sie abzurufen.
Kachelobjekt
Erstellen Sie ein weiteres leeres Objekt, das zur Visualisierung der Kacheln in unserem Raster verwendet wird. Sein Maßstab ist ebenfalls 50% und hat nur ein vordefiniertes Attribut: „auf Kachel“. Setzen Sie auch diesen Wert auf null.
Blockadeobjekt
Erstellen Sie ein weiteres leeres Objekt, das als Blockade in unserem Raster dient. Dies ist ein weißes leeres Objekt mit einem Maßstab von 40%. Unser Avatar wird nicht in der Lage sein, auf eine Kachel zu gelangen, die eine Blockade darauf hat.
Rasteretikett
Dies ist nur ein Etikett, das über die Verhaltensweisen verfügt, die die Einrichtung und Visualisierung unseres Rasters ermöglichen. Es hat vordefinierte Attribute: Start-x mit einem Wert von 4 und Start-y mit einem Wert von 3. Diese Werte sind Offsets, die als Referenz verwendet werden, wenn wir unsere Kacheln spawnen, um unser Raster ordentlich in die Mitte zu positionieren.
Avatar/Kachel vordefinierte Attribute:
Wir definieren hier eine Kachel als ein 2-größiges Array, das einen x- und y-Wert basierend auf unserem Raster haben wird.
- auf Kachel - dies ist der Kachelwert, auf dem sich unser Objekt aktuell in unserem Raster befindet
- vorherige Kachel - eine Kachel, die zuvor von unserem Avatar betreten wurde
- Zielkachel - die Kachel, auf die unser Avatar gehen wird
II. Raster einrichten
Im Rasteretikett definieren wir unser 2D-Array und das Spawnen unseres Rasters. Es gibt 2 Hauptschwerpunkte in diesem Objekt: das Array festlegen und das Array visualisieren. Lassen Sie uns zuerst das Set-Array-Bundle durchführen.
Array setzen - Paket
Zuerst erstellen wir ein leeres Array mit dem Namen „Raster“. Dieses Array wird unser 2-dimensionales Array enthalten. Wir haben einen Boxcontainer namens „x-Reihenanzahl“, der einen Wert von 24 hat, und ein weiteres leeres Array namens „y-Reihe“, das 18 leere Werte hat.
Das erste Verhalten in unserem Bundle ist eine Schleife mit einer Wiederholungszahl von „x-Reihenanzahl“. Für jeden Schritt dieser Schleife fügen wir eine leere y-Reihe zum „Raster-Array“ hinzu. Dadurch wird ein Array innerhalb eines Arrays mit einer Dimension von 24x18 erstellt.
Bitte beachten Sie, dass wir zu Beginn unseres Bundles einen inaktiven Kommentar verbunden haben, um die automatische Ausführung dieses Wurzelverhaltens zu negieren. Ein Wurzelverhalten ist ein Verhalten, das nicht durch ein Ereignis ausgelöst wird und offen in der Benutzeroberfläche platziert wird.
Raster visualisieren - Paket
Das Hauptziel, das wir hier verfolgen, ist das Durchlaufen jedes Wertes unseres „Raster-Arrays“ und das Spawnen eines Kachelobjekts. Wir werden in unserer Schleife auch eine Bedingung hinzufügen, die das Spawnen einer weißen Blockade auf dem Kachelobjekt ermöglicht.
Als erstes rufen wir die Anzahl des Arrays unserer „y-Reihenarray“, den „Start-x“-Attributwert dieses Objekts und den „Start-y“ auf.
Erstellen Sie eine Schleife, die eine Wiederholung der „x-Reihenanzahl“ hat, und für jeden Schritt dieser Schleife fügen wir den Indexwert dieser Schleife und den „Start-x“-Attributwert hinzu. Dies ergibt eine absolute x-Position, die wir später verwenden werden, um unsere gespawnten Kacheln zu positionieren. Als nächstes ist die „y-Reihen-Schleife“, die eine Wiederholung der „y-Reihenanzahl“ hat. Für jeden Schritt dieser Schleife fügen wir den Indexwert dieser Schleife und den „Start-y“-Attributwert hinzu, was nun zur absoluten y-Position führt.
Nachdem die Werte unter der „y-Reihen-Schleife“ hinzugefügt wurden, ist es Zeit, das blaue Objekt zu spawnen. Setzen Sie die # of alive objects darauf auf 999, da wir eine Menge davon für unser Raster benötigen werden, und auch mit einer Dauer von 0. Bewegen Sie dann das gespawnte Objekt zu einem x-Punkt mit dem Wert vom x-Schleifen ‚add values‘ und dem y-Punkt von Wert vom y-Schleifen ‚add values‘.
N als nächstes müssen wir ein Array mit 2 leeren Werten namens „Auf Kachel“ hinzufügen, das wir nur als Platzhalter für das Array verwenden werden. Nachdem das Kachelobjekt verschoben wurde, ändern Sie das „Auf Kachel“-Array, indem Sie seinen Wert am Index 0 mit dem Wert der „x-Reihen-Schleife“ ersetzen. Dann fügen Sie eine weitere Array-Modifikation hinzu, die den Wert am Index 1 mit „y-Reihen-Index“ ersetzt. Dies sind die x- und y-Koordinaten unseres Rasters, die das Objekt als „auf Kachel“-Attribut hat.
Jetzt setzen Sie das Attribut des gespawnten Objekts mit einem dynamischen Schlüssel, „auf Kachel“, und mit einem Wert von „Auf Kachel - Array“.
Immer noch unter der y-Reihen-Schleife befindet sich die Bedingung für das Spawnen des weißen Blockadeobjekts. Wir werden eine 2 von 5 Chance haben, dieses Bundle auszuführen, was unserer Rasteranpassung eine Zufälligkeit verleiht. Dann setzen wir einen Wert von 1 für die x- und y-Koordinate in unserem „Raster“-Array, was uns sagt, dass diese Koordinate eine gespawnte Blockade hat.
Zuerst fügen wir eine Zufallszahl von 1 bis 5 hinzu. Wenn diese Zahl kleiner oder gleich 2 ist, spawnieren wir die Blockade. Setzen Sie ihre # Alive-Objekte auf 999 und bewegen Sie dieses Objekt zu demselben Punkt wie die blaue Kachel, die wir zuvor gespawnt haben, und ebenfalls mit einer Dauer von 0.
Als nächstes speichern wir die Information, dass diese Koordinate von einer Blockade belegt wurde, wenn sie gespawnt wurde. Wir tun dies, indem wir diese Koordinate mit einem Wert von 1 markieren. Zuerst rufen wir den Wert am Index ‚x-Reihen-Schleife‘ des „Raster“-Arrays ab. Dieser Wert gibt uns ein Array einer „y-Reihen“. Wir modifizieren diese „y-Reihen“, indem wir ihren Wert am Index „y-Reihen-Schleife“ durch den Wert 1 ersetzen, der der markierte Wert ist. Da diese Wertmodifikation nur auf diesen Wert und nicht auf das „Raster“ selbst anwendbar ist, müssen wir das „Raster“-Array weiterhin modifizieren. Ersetzen Sie den Wert am Index „x-Reihen-Schleife“ des „Raster“-Arrays durch den Wert „modify y row - array“.
Sobald gespielt wird, sollte es zu dieser Art von Form führen.
III. Bei Kachel drücken
Um mit dem Raster selbst interagieren zu können, benötigen wir ein Bundleverhalten, wann immer wir auf eine blaue Kachel drücken. Der erste Druck führt zur Erscheinung unseres Avatars in unserem Raster, und jeder nachfolgende Druck nach diesem Ereignis wird mit dem Pfadsuchen beginnen.
Im blauen Objekt befindet sich ein Verhaltenspaket, das 3 Hauptpunkte hat: das Zurücksetzen der vorherigen Kachel unseres Avatars, das Setzen des „auf Kachel“/Setzen des „Zielkachel“ und dann das Einrichten einer Farbanimation, um das Berührungsereignis auf dem Bildschirm zu visualisieren.
Zuerst holen wir das „auf Kachel“-Attribut des Kachelobjekts. Setzen Sie das „vorherige Kachel“-Attribut unseres Avatars auf 0. Unser Avatar wird so eingestellt, dass er vermeidet, zu einer „vorherigen Kachel“ zurückzukehren, weshalb wir das „vorherige Kachel“ bei jedem Kachel-Druck zurücksetzen.
Als nächstes holen wir uns das „auf Kachel“-Attribut unseres Avatars. Die erste Bedingung lautet, ob der Wert „auf Kachel“ gleich null ist. Das bedeutet, dass unser Avatar noch nicht erschienen ist, wenn dies wahr ist. Wenn es wahr ist, setzen wir sein Attribut „auf Kachel“ mit dem Wert des „auf Kachel“-Attributs des Kachelobjekts. Dann bewegen wir die Position unseres Avatars, indem wir die Position des Kachelobjekts abrufen und seine x- und y-Werte auf diesen Punkt mit einer Dauer von 0 setzen.
Wenn der Wert „auf Kachel“ nicht null ist, setzen wir das Attribut „Zielkachel“ unseres Avatars mit dem „auf Kachel“-Attributwert des Kachelobjekts. Das bedeutet, dass unser Avatar bereits in unserem Raster ist, und dann können wir das Verhaltenspaket „Pfad finden“ ausführen. Dieses Verhalten haben wir jedoch noch nicht, aber wir werden dies später nach dem weiteren Verlauf dieses Tutorials für das Paket „Pfad finden“ beheben.
Jetzt, wo wir unseren Avatar richtig in unser Raster gesetzt haben, müssen wir nur noch dieses Druckereignis visualisieren. Zuerst müssen wir ein Wurzelverhalten „Get Color“ verwenden, um seine ursprüngliche Farbe zu erhalten. Dann setzen wir, nachdem das Druckereignis, die Farbe des Kachelobjekts auf schwarz mit einer Dauer von 0 und setzen auch seine Farbe wieder auf den ursprünglichen Wert mit einer Dauer von 0,2.
Ein Druck auf eine blaue Kachel sollte zu diesem Ergebnis führen.
IV. Bundle „Pfad finden“ ausführen
Für diesen letzten Teil unseres Tutorials werden wir den Algorithmus einrichten, der uns ermöglicht, die nächste Kachel zu finden, die unser Avatar nehmen kann, um sein Ziel zu erreichen. Dieses Bundle wird wiederholt für jeden Kachel-Schritt ausgeführt, den unser Avatar auf unserem Raster bewegt.
Wir werden den Algorithmus innerhalb unseres Avatar-Objekts einrichten und das hat drei Hauptpunkte: das Finden benachbarter Kacheln, das Finden der nächsten benachbarten Kachel und die Bewegung zu dieser benachbarten Kachel.
Finden der benachbarten Kacheln
In diesem Teil sammeln wir alle benachbarten Kacheln, die unser Avatar durchqueren kann. Wir werden die vier benachbarten Kacheln in den Richtungen überprüfen und sehen, ob diese Kacheln eine Blockade darauf haben oder ob sie zuvor betreten wurden.
Als erstes fügen wir unser „Benachbarte Kacheln“-Array hinzu. Ein „Richtung“-Array mit 2 leeren Werten und den vier Richtungsarrays, die jeweils 2 Werte haben: N (0,1), S (0,-1), E (1,0), W( -1,0).
Das erste Verhalten in unserem Bundle ist das Löschen unserer benachbarten Kacheln. Da wir dieses Bundle wiederholt ausführen, müssen wir die gesammelten „benachbarten Kacheln“ jedes Mal zurücksetzen. Die nächsten vier Verhaltensweisen sind Modifikationen des „Richtung“-Arrays. Wir setzen das Array des „Richtung“-Arrays viermal mit den vier Richtungsarrays und führen dann das untenstehende Bundle aus. Das tun wir, um eine Schleife mit verschiedenen „Richtung“-Array-Werten jedes Mal zu erstellen.
Jetzt, da wir die Richtung haben, müssen wir nur noch deren x- und y-Werte mit dem „auf Kachel“-Attribut unseres Avatars kombinieren. Dann können wir unseren Zielwert im „Raster“-Array abrufen, um zu wissen, ob diese Kachel mit einer Blockade markiert wurde.
„Richtung x“ ist der Wert des „Richtung“-Arrays am Index 0, „get on tile x“ ist der Wert von „get on tile“ am Index 0. „Ziel x“ ist der additive Wert von „Richtung x“ und „get on tile x“. Gleiches gilt für die y-Werte, jedoch mit einem Zielindex von 1.
„Ziel y-Reihe“ ist der Array-Wert des „Raster“-Arrays am Index „Ziel x“. Und dann wird der „Zielindex in der y-Reihe“ der Wert des „Ziel y-Reihe“-Arrays am Index des „Ziel y“ sein. Das ist die Koordinate in unserem Raster, die uns sagen wird, ob sie mit einer Blockade markiert wurde.
Wenn der Wert in „Zielindex in y-Reihe“ 1 beträgt, dann ist diese Zielkachel als blockiert markiert. Wenn der Wert jedoch nicht 1 beträgt, können wir mit unserem Bundle fortfahren.
Da unser Ziel x und y unsere Bedingung bestanden haben, haben wir ein neues leeres Kachelarray namens „Neue benachbarte kachel“ hinzugefügt. Dies speichert die Werte von Ziel x und y als Kachelarray. Wir setzen den Wert von Ziel x auf den Index 0 von „Neue benachbarte Kachel“ und Ziel y auf seinen Index 1.
Holen Sie sich jetzt das Attribut „vorherige Kachel“ unseres Avatars. Wenn die „vorherige Kachel“ nicht gleich der „neuen benachbarten Kachel“ ist, bedeutet das, dass die neue Kachel zuvor nicht durchquert wurde. Dann können wir sicher die „Neue benachbarte Kachel“ zur „Benachbarte Kacheln“-Array hinzufügen, indem wir sie anhängen. Wir setzen den Wert der „vorherigen Kachel“ später, nachdem unser Avatar erfolgreich zu einer anderen Kachel bewegt wurde.
"Sie können dieses Bundle erweitern, indem Sie ein 8-Richtungs-Array erstellen, das es Ihrem Avatar ermöglicht, sich in diagonale Richtungen zu bewegen."
Finden der nächsten benachbarten Kachel
Jetzt, da wir unsere zuverlässigen benachbarten Kacheln gesammelt haben, müssen wir nur noch die benachbarte Kachel finden, die unserem Zielkachel unseres Avatars am nächsten ist. Wir werden die Berechnung mit einer Distanzformel durchführen, die durch die x- und y-Werte unserer Zielkachel und der benachbarten Kacheln bereitgestellt wird.
Es gibt zwei Hauptpunkte in diesem Bundle: die Initialisierung der Variablen für die Berechnung und die Berechnung der Kachelabstände innerhalb einer Schleife.
a. Initialisierung der Variablen
Zuerst holen wir uns die Anzahl der „benachbarten Kacheln“. Dann erhalten wir das „Zielkachel“-Attribut unseres Avatars und holen seine x- und y-Werte. Wir fügen 2 neue Boxcontainer hinzu: die „Min Distanz“ und den „Zielkachelindex“. Wir setzen den Anfangswert von „Min Distanz“ auf 9999 und den Wert von „Zielkachelindex“ auf 0. Die Mindestdistanz wird auf eine hohe Zahl gesetzt, da wir die geringste Entfernung vom Startwert benötigen. Der Zielkachelindex ist unser Referenzindex im „Benachbarte Kacheln“-Array, der die geringste Distanz zu unserem „Zielkachel“ hat.
Unser Hauptziel hier ist es, den Index der Kachel im „Benachbarte Kacheln“-Array zu erhalten, die am nächsten zu unserem „Zielkachel“ liegt.
b. Berechnung der Kachelabstände
In diesem Bundle führen wir die Berechnung innerhalb einer Schleife aus, die wir für jede benachbarte Kachel durchführen werden. Die Schleife wird nach der „Anzahl benachbarter Kacheln“ wiederholt und wir holen uns den Kachelwert des „Benachbarte Kacheln“-Arrays unter Verwendung des Index dieser Schleife.
Holen Sie sich die x- und y-Werte dieser benachbarten Kachel und berechnen Sie dann die Distanz zwischen unserem „Zielkachel“ und der „benachbarten Kachel“ mit dieser Formel:
distance = sqrt((x2 - x1)^2+(y2 - y1)^2)
x1 = Ziel x
x2 = benachbartes x
y1 = Ziel y
y2 = benachbartes y
Zuerst subtrahieren wir deren x- und y-Werte, multiplizieren sie mit sich selbst, um die exponentiellen Werte zu erhalten, addieren diese Werte und ziehen dann die Quadratwurzel des hinzugefügten Wertes, um den Distanzwert zu erhalten.
Wenn der Wert der „Distanz“ kleiner ist als der Wert des „Min Distanz“-Boxcontainers, setzen wir dann den Wert von „Zielkachelindex“ auf den aktuellen Index der Schleife, der der Index unserer abgerufenen Kachel im „Benachbarte Kacheln“-Array ist. Wir setzen auch den Wert des „Min Distanz“-Boxcontainers mit dem „Distanz“-Wert, um diesen mit dem nächsten Kachel unserer Schleife zu vergleichen.
Nach dem Ende der Schleife haben wir jede unserer benachbarten Kacheln verglichen, und wir haben den Indexwert der benachbarten Kachel, die unserem „Zielkachel“ am nächsten ist, erhalten.
Bewegung zur benachbarten Kachel
In diesem letzten Bundle unseres Tutorials bewegen wir unseren Avatar zur nächsten benachbarten Kachel und wiederholen die gesamte „Pfad finden“-Bundles, wenn wir noch nicht zu unserer „Zielkachel“ gewechselt sind.
Das erste, was wir tun müssen, ist zu überprüfen, ob unsere „Anzahl benachbarter Kacheln“ größer als 0 ist. Damit stellen wir sicher, dass wir nur dann umziehen, wenn wir mindestens eine zuverlässige benachbarte Kachel abgerufen haben.
Dann „Holen Sie sich die nächste Kachel“ mithilfe unseres „Zielkachelindex“-Wertes aus dem vorherigen Bundle, um den Arraywert des „Benachbarte Kacheln“-Arrays zu erhalten.
Um den genauen Punkt zu erhalten, zu dem unser Avatar sich bewegen wird, benötigen wir die x- und y-Kachelwerte dieser Kachel sowie die „Start x“- und „Start y“-Attributwerte unseres „Raster“-Labels. Wir addieren dann den x-Wert unserer „nächsten Kachel“ und den „Start x“-Wert sowie das Gleiche mit den y-Werten. Diese hinzugefügten Werte sind unsere Ziel-x- und Ziel-y-Punkte, zu denen sich unser Avatar bewegen wird.
Bevor wir zu diesem Punkt bewegen, setzen wir das „vorherige Kachel“-Attribut unseres Avatars auf den aktuellen „auf Kachel“-Attributwert. Wir können diesen „auf Kachel“-Wert aus den vorherigen Bundles abrufen. Dann bewegen wir unseren Avatar zu unseren Zielpunkten mit einer Dauer von 0.2.
Nach Abschluss des „Bewege zu Punkt“-Verhaltens setzen wir nun den „auf Kachel“-Attributwert unseres Avatars mit dem „Hol die nächste Kachel“-Arraywert. Wenn der „Hol die nächste Kachel“-Arraywert nicht gleich unserem „Zielkachel“ ist, führen wir dann das „Pfad finden“-Bundle aus, und somit wiederholen wir das gesamte Bundle erneut. Der „Zielkachel“-Attributwert kann aus dem vorherigen Bundle abgerufen werden.
Indem Sie auf eine beliebige blaue Kachel drücken und nachdem unser Avatar im Raster erscheint, wird das „Pfad finden“-Bundle ausgeführt. Dies wird die Bewegung des Avatars von Kachel zu Kachel auslösen.
Fazit
In diesem Tutorial haben wir gelernt, eine Objekt-Pfadsuchaktivität unter Verwendung eines Arrays, das wir „Raster“ genannt haben, zu erstellen, das dazu dient, Informationen zu speichern, ob diese Kachel belegt oder nicht ist. Sie können diese Idee erweitern, indem Sie Objekt-IDs als Informationsspeicher verwenden, anstatt nur eine Zahl für unser „Raster“-Array zu verwenden. Dies wird uns zuverlässigere Informationen geben, die wir bei der Pfadsuche verwenden können. Zum Beispiel können wir die Attribute dieser Objekt-ID abrufen, um zu wissen, ob es lebendig oder nicht ist und ob es uns erlaubt, auf dessen Kachel zu treten oder nicht.
Dieses Tutorial bietet nur die grundlegende Idee hinter der Pfadsuche. Ein Nachteil ist, dass es keinen kürzesten Weg zu einer Zielkachel erstellt und nur die aktuellen benachbarten Kacheln überprüft. Dies kann zu einer Bewegungsloop führen, die nirgendwo hinführt.
Dies kann jedoch gelöst werden, indem wir unseren Pfadsuchalgorithmus erweitern. Wir können dies tun, indem wir unsere abgerufenen benachbarten Kacheln wiederholt, um deren benachbarte Kacheln abzurufen, bis wir unsere Zielkachel finden. Jede gefundene nächste benachbarte Kachel wird einer Liste hinzugefügt. Um eine unendliche Schleife zu vermeiden, fügen Sie eine Bedingung hinzu, dass diese benachbarte Kachel, wenn sie bereits überprüft wurde, nicht zu unserer Liste hinzugefügt wird. Fügen Sie auch eine maximale Begrenzung der Wiederholungsanzahl hinzu, um eine unendliche Schleife zu verhindern, die durch die Zielkachel verursacht wird, wenn sie zu weit entfernt oder nicht gefunden werden kann. Sobald diese Iteration die Zielkachel findet, beenden wir diese Iteration und beginnen damit, den Avatar von Kachel zu Kachel mithilfe der Kachelliste zu bewegen.

