Rács alapú útvonalkeresés | hyperPad Documentation
Logo

Ebben a bemutatóban egy útvonalkeresési szimulációt készítünk egy 2-dimenziós tömb alapú rács alapján. Ez megadja nekünk az alapvető ötletet az útvonalkeresési tevékenységek létrehozásához a játékainkban. A rácsot üres négyzet objektumokkal fogjuk vizualizálni, mint csempék, és egy kerek objektumként, mint avatár, amely a parancsunkkal mozoghat ezen a rács területen.

Rács alapú útvonalkeresés

I. Az objektumok beállítása

Csak négy objektumot fogunk használni a projektünkben. Zöld avatárunk, egy kék csempe, egy fehér blokk és a rács címkéje a rácsunk beállításához és vizualizálásához.

Rács alapú útvonalkeresés

Avatár

Az avatárunk egy üres objektum, amelynek az x és y mérete 50%. A ütközését kerek formára állítsuk, hogy olyan legyen, mint az alábbi képen. Ennek az objektumnak három előre meghatározott attribútuma lesz: a csempén, a korábbi csempe, és a célcsempe. Ezeket az attribútumokat alapértelmezetten nullára kell állítani, hogy ne legyen null értékük, amikor később megpróbáljuk elérni őket.

Rács alapú útvonalkeresés

Csempe Objektum

Hozzunk létre egy másik üres objektumot, amelyet a rácsunkban a csempék vizualizálására fogunk használni. Ez is 50%-os méretű, és csak egy előre meghatározott attribútuma van: csempén. Állítsuk ezt az értéket is nullára.

Rács alapú útvonalkeresés

Blokkoló Objektum

Hozzunk létre egy másik üres objektumot, amely blokként fog szolgálni a rácsunkban. Ez egy fehér üres objektum, amelynek a mérete 40%. Az avatárunk nem tud átkelni arra a csempére, amelyen blokk található.

Rács Címke

Ez csupán egy címke, amely olyan viselkedéseket tartalmaz, amelyek lehetővé teszik a rácsunk beállítását és vizualizálását. Előre meghatározott attribútumai vannak: kezdő x érték 4, kezdő y érték 3. Ezek az értékek eltérések, amelyeket a csempék elhelyezéséhez fogunk használni, hogy a rácsunk szépen a középre kerüljön.

Rács alapú útvonalkeresés

Avatár/Csempe előre meghatározott attribútumai:

Itt egy csempét egy 2-dimenziós tömbként definiálunk, amely x és y értékekkel fog rendelkezni a rácsunk alapján.

  • csempén - ez az a csempeérték, amin az objektumunk jelenleg áll a rácsunkban
  • korábbi csempe - a csempe, amelyet korábban járt be az avatárunk
  • célcsempe - az a csempe, ahova az avatárunk megy

II. A rács beállítása

A rács címkéjén belül definiáljuk a 2D tömbünket és a rácsunk létrehozását. Ennek az objektumnak 2 fő szempontja van: a tömb beállítása, és a tömb vizualizálása. Először a beállító tömb csomagot csináljuk.

Rács alapú útvonalkeresés

A tömb beállítása - csomag

Első lépés egy üres tömb létrehozása, amelynek neve 'Rács'. Ez a tömb a 2-dimenziós tömbünket fogja tartalmazni. Lesz egy doboz konténerünk, amelynek neve 'x sor szám', értéke 24, és egy másik üres tömb, amelynek neve 'y sor', amely 18 üres értéket tartalmaz.

Rács alapú útvonalkeresés

A csomagunk első viselkedése egy ciklus, amely a 'x sor szám' számú ismétlésből áll. Ennek a ciklusnak minden lépésében hozzáadunk egy üres y sort a 'Rács tömbhöz'. Ez egy tömböt hoz létre a rácsunkban mérettel 24x18.

Észrevettük, hogy a csomagunk elején van egy inaktív komment, hogy megakadályozzuk a gyökér viselkedés automatikus végrehajtását. A gyökér viselkedés olyan viselkedés, amely nem indítódik el események alapján, és nyíltan a felületen helyezkedik el.

A rács vizualizálása - csomag

Amit itt fogunk csinálni, az az, hogy az 'Rács tömb' minden értékén átmegyünk, és létrehozunk egy csempe objektumot. A ciklusunkba kondíciókat is hozzáadunk, amelyek lehetővé teszik, hogy fehér blokkot helyezzünk el a csempe objektumok fölött.

Rács alapú útvonalkeresés

Először is meg kell kapnunk az 'y sor tömb' számát, az objektum 'kezdő x' attribútumának értékét és a 'kezdő y' attribútum értékét.

Hozzuk létre a ciklust, amely 'x sor számú' ismétléssel rendelkezik, és minden ilyen lépésben hozzáadjuk a ciklus index értékét a 'kezdő x' attribútum értékéhez. Ez egy abszolút x pozíciót eredményez, amelyet később a felnövekvő csempe pozicionálásához fogunk használni. A következő lépés a 'y sor ciklus', amely 'y sor számú' ismétléssel rendelkezik. Minden ilyen lépésben hozzáadjuk a ciklus index értékét a 'kezdő y' attribútum értékéhez, amely most abszolút y pozíciót eredményez.

Rács alapú útvonalkeresés

Miután hozzáadtuk az értékeket a 'y sor ciklus alatt', egy kék objektumot hozunk létre. Állítsuk be az életben lévő objektumok számát 999-re, mert sokra szükségünk lesz a rácsunkhoz, és a tartam is 0. Ezután mozgassuk a létrehozott objektumot egy x pontra, amely az x ciklus 'hozzáadott értékeiből' származik, és a y pontra az y ciklus 'hozzáadott értékeiből'.

Következő lépésként adjunk hozzá egy tömböt 2 üres értékkel, amelyet 'Csempén' néven fogunk hívni, amelyet csupán tömb helyett használunk. Miután elmozdítottuk a csempe objektumot, módosítsuk a 'Csempén' tömböt azzal, hogy 0 indexnél az értékét felváltjuk a 'y sor ciklus' értékével. Ezután adjunk hozzá egy új tömb módosítást, amelyben a 1. indexben a 'y sor index' értékét helyettesítjük. Ez a rácsunk x és y koordinátái, amelyek az objektumunk 'csempén' attribútumaként fognak szerepelni.

Most állítsuk be a létrehozott objektum attributumát egy dinamikus kulccsal, 'csempén', és a 'Csempe - tömb' értékével.

Rács alapú útvonalkeresés

Még mindig a 'y sor ciklus alatt' vannak a feltételek a fehér blokk létrehozásának. Azt fogjuk tenni, hogy 2 az 5-höz az esély, hogy ezt a csomagot végrehajtsuk, ami hozzáadja a véletlenszerűséget a rácsunkhoz. Ezután a 'Rács' tömbben 1 értéket állítunk be az x és y koordinátáknál, ami azt jelzi, hogy az adott koordinátán blokk él.

Először is, kapjunk egy véletlen számot 1 és 5 között. Ha ez a szám kevesebb vagy egyenlő 2-vel, akkor létrehozunk egy blokkot. Állítsuk be az élő objektumok számát 999-re, és mozgassuk ezt az objektumot a korábban létrehozott kék csempe ugyanarra a pontra, szintén 0 tartammal.

Következő lépésként tároljuk az információt, hogy a koordinátát blokkolták, ha létrejöttek. Ezt úgy tudjuk megtenni, hogy azt az koordinátát 1 értékkel megjelöljük. Először is kapjuk meg az 'x sor ciklus' értékét a 'Rács' tömbből. Ez az érték egy 'y sor' tömböt ad nekünk. Módosítjuk ezt a 'y sort' azzal, hogy felváltjuk a 'y sor ciklus' értékét 1-re, amely a megjelölt érték. Mivel ez az érték módosítás csak az értékre vonatkozik, és nem a magára a 'Rács'-ra, vagyis a 'Rács' tömböt is módosítanunk kell. Cseréljük ki a 'Rács' tömb 'x sor ciklus' indexét az 'előző y sor - tömb' értékkel.

Miután a játékot játszottuk, ennek ilyen formának kellene lennie.

Rács alapú útvonalkeresés

III. Csempe megnyomása

A rács interakciójához szükségünk van egy csomag viselkedésre, amikor megnyomunk egy kék csempét. Az első nyomás eredménye az avatárunk megjelenése a rácsunkban, és minden további nyomás után elkezdődik az útvonalkeresése.

A kék objektumokon olyan viselkedési csomag található, amely három fő lépést tartalmaz: az avatárunk korábbi csempe értékének visszaállítása, a csempe beállítása/beállítása a célcsempe, majd szín animáció hozzáadása, hogy vizualizáljuk a nyomógomb eseményt a képernyőn.

Rács alapú útvonalkeresés

Először is, kapjuk meg a csempe objektum 'csempén' attribútumát. Állítsuk be az avatárunk 'korábbi csempe' attribútumát 0-ra. Az avatárunkat úgy állítjuk be, hogy elkerülje, hogy visszatérjen egy 'korábbi csempe' értékhez, ezért minden csempe nyomáskor visszaállítjuk a 'korábbi csempe' értékét.

Következő lépés, hogy megkaphassuk az avatárunk 'csempén' attribútumát. Az első if feltétel az, hogy a 'csempe' értéke 0, azaz ha az avatárunk még nem jelent meg, akkor ez igaznak kell lennie. Ha igaz, akkor beállítjuk az 'csempe' attribútumot a csempe objektum 'csempe' attribútuma értékére. Ezután az avatárunk pozícióját a csempe objektum pozíciójára állítjuk, az x és y értékeket a pontra állítva, tartam 0.

Ha a 'csempe' értéke nem egyenlő 0-val, akkor beállítjuk az avatárunk célcsempe attribútumát a csempe objektum 'csempén' attribútumának értékére. Ez azt jelenti, hogy az avatárunk már a rácsunkban van, és végrehajthatjuk a csomag viselkedést, az 'útvonalkeresést'. Még nincs meg ez a viselkedésünk, de ezt a bemutató későbbi részében kijavítjuk, amikor a 'útvonalkereső' csomagra kerül a sor.

Most, hogy helyesen beállítottuk az avatárunkat a rácsunkhoz, csupán a megnyomási esemény vizualizálására van szükségünk. Először a gyökér viselkedéssel kapjunk egy színt, hogy szerezze meg az eredeti színét. Majd a nyomás eseménye után beállítjuk a csempe objektum színét feketévé 0 tartammal, majd visszaállítjuk az eredeti színére 0.2 tartammal.

A kék csempe megnyomásának eredménye a következőképpen kell, hogy kinézzen.

Rács alapú útvonalkeresés

IV. Az útvonalkereső csomag végrehajtása

A bemutatónk utolsó részén megvalósítjuk az algoritmust, amely lehetővé teszi számunkra, hogy megtaláljuk a legközelebbi csempét, amelyet az avatárunk elérhet a céljához. Ezt a csomagot ismételten végrehajtjuk minden csempe lépés során, amelyen az avatárunk a rácsunkon mozog.

Az algoritmust belül a avatár objektumunkban állítjuk be, és három fő lépésből áll: a szomszédos csempék megtalálása, a legközelebbi szomszédos csempe megtalálása, és a mozgás a szomszédos csempére.

Rács alapú útvonalkeresés

A szomszédos csempék megtalálása

Ebben a részben összegyűjtjük az összes szomszédos csempét, amelyet az avatárunk átléphet. Ellenőrizzük a négy irányban elhelyezkedő szomszédos csempéket, és megnézzük, hogy vannak-e blokkok a tetejükön, vagy hogy korábban léptek-e a rácsunkra.

Rács alapú útvonalkeresés

Először hozzáadunk egy 'Szomszédos csempék' tömböt. Egy 'Irány' tömb két üres értékkel, és a négy irányú tömbök, amelyeknek mindenik 2 értéke van: Észak (0,1), Dél (0,-1), Kelet (1,0), Nyugat (-1,0).

A csomagunk első viselkedése az, hogy töröljük a szomszédos csempéket. Mivel ezt a csomagot ismételten végrehajtjuk, szükségünk van a 'gyűjtött szomszédos csempék' visszaállítására minden alkalommal. A következő négy viselkedés a 'Irány' tömb módosításai. A 'Irány' tömb négy alkalommal állítja be a négy irányú tömböt, majd a következő csomagra lépünk. Ezt úgy tesszük, hogy különböző 'Irány' tömb értékekkel is létrehozunk egy ciklust.

Rács alapú útvonalkeresés

Most, hogy van irányunk, csak annyit kell tennünk, hogy egyesítjük az ő x és y értékeiket az avatárunk 'csempén' attribútumával. Ezután a célértéket elérjük a 'Rács' tömbben, hogy megtudjuk, hogy a csempe blokkolva van-e.

'Irány x' az 'Irány' tömb 0 indexénél lévő érték, a 'csempe x' az x értéke a 'csempe x' indexén. A cél x a 'irány x' és 'csempe x' összeadott értéke. Ugyanez a y értékekben, de a cél indexe 1.

'Cél y sor' a 'Rács' tömb értéke 'Cél x' indexén. A 'Cél index' a 'Cél y sor' tömb értéke a 'Cél y' indexén. Ez a koordináta a rácsunkban, amely meg tudja mondani, hogy az blokkolva van-e.

Rács alapú útvonalkeresés

Ha a 'Cél index' y sorban lévő értéke 1, az azt jelenti, hogy az a csempe blokkolva van. De ha az érték nem egyenlő 1-gyel, akkor folytathatjuk a csomagot.

Mivel a Cél x és y áthaladt a feltételünkön, hozzáadtunk egy új üres csempe tömböt, amelyet 'Új szomszédos csempe'-ként hívunk. Ez a cél x és y értékeket fogja tárolni csempe tömbként. Beállítjuk a cél x értékét a 'Új szomszédos csempe' 0 indexére, és a cél y értékét az 1 indexére.

Most kapjuk meg az avatárunk 'korábbi csempe' attribútumát. Ha a 'korábbi csempe' nem egyenlő az 'új szomszédos csempe'-val, az azt jelenti, hogy az új csempe nem volt korábban bejárva. Ezért biztonságosan hozzáadhatjuk az 'Új Szomszédos csempe' tömböt a 'Szomszédos csempék' tömbhöz azáltal, hogy hozzáadjuk azt.

"Bővítheti ezt a csomagot úgy, hogy készítsen egy 8 irányú tömböt is, amely lehetővé teszi avatárjának a diagonális irányokban való mozgatását."

A legközelebbi szomszédos csempe megtalálása

Most, hogy összegyűjtöttük megbízható szomszédos csempéinket, csak annyit kell tennünk, hogy megtaláljuk azt a szomszédos csempét, amelyik a legközelebb van az avatárunk célcsempéjéhez. A számítást a célcsempe és a szomszédos csempék x és y értékeinek felhasználásával végezzük.

Ennek a csomagnak két fő szempontja van: a változók inicializálása a számításhoz, és a távolságok kiszámítása a csempe mellett lévő csempékben egy cikluson belül.

a. A változók inicializálása

Először is, meg kell kapnunk a szomszédos csempék számát. Ezután megkapjuk az avatárunk 'célcsempe' attribútumát, és megkapjuk az x és y értékeit. Hozzáadunk 2 új doboz konténert: a 'Min távolság' és a 'Cél csempe index'. A 'Min távolság' kezdeti értékét 9999-re állítjuk, a 'Cél csempe index' értékét pedig 0-ra. A min távolságot magasan állítjuk, hogy a kezdeti távolság a legkisebb legyen. A célcsempe index az a referenciaindex a 'Szomszédos csempék' tömbben, amely a legkisebb távolságot mutat a célcsempe felé.

Fő célunk itt, hogy megkaphassuk a szomszédos csempe távolságot a 'Szomszédos csempék' tömbben, amelyik a legközelebb van a 'célcsempéhez'.

Rács alapú útvonalkeresés

b. A csempe távolságának kiszámítása

Ebben a csomagban a számítást egy ciklusban végezzük el, amelyet minden szomszédos csempére végrehajtunk. A ciklus az 'szomszédos csempék számán' ismétlődik, és a ciklus indexét használva megszerezzük a 'Szomszédos csempék' tömb csempeértékét.

Kapjuk meg a csempe x és y értékeit, majd kiszámítjuk a távolságot a 'célcsempe' és a 'szomszédos csempe' x és y értékeivel a következő képlet alkalmazásával:

távolság = sqrt((x2 - x1)^2+(y2 - y1)^2)
x1 = Cél x
x2 = Szomszédos x
y1 = Cél y
y2 = Szomszédos y

Először levonjuk az x és y értékeket, majd megszorozzuk azt saját magával, hogy megkapjuk az exponenciális értékeket. Az így kapott értékeket összeadjuk, majd gyököt vonunk az összegből, hogy megkapjuk a távolság értékét.

Rács alapú útvonalkeresés

Ha a 'Távolság' értéke kisebb, mint a 'Min távolság' doboz értéke, akkor beállítjuk a 'célcsempe index' értékét a ciklus aktuális indexére, amely a begyűjtött csempe indexe a 'Szomszédos csempék' tömbben. A 'Min távolság' doboz értékét a 'Távolság' értékre állítjuk, hogy a következő csempével hasonlíthassuk össze.

Miután a ciklus lezárult, összehasonlítottuk a szomszédos csempéinket, és megkaptuk az index értékét a csempének, amelyik a legközelebb van a 'célcsempéhez'.

Mozgás a szomszédos csempére

A bemutatónk utolsó csomagjában az avatárunkat a legközelebbi szomszédos csempére fogjuk mozgatni, és újra végrehajtjuk az egész 'Útvonalkereső' csomagot, ha még nem léptünk el a 'célcsempénktől'.

Rács alapú útvonalkeresés

Először is ellenőrizzük, hogy az 'szomszédos csempék szám' nagyobb, mint 0. Ez biztosítja, hogy csak akkor mozgunk, ha legalább egy megbízható szomszédos csempét gyűjtöttünk be.

A 'Legközelebbi csempe' nevével az 'Cél csempe index' értékét fogjuk felhasználni, hogy megkapjuk a 'Szomszédos csempék' tömb jellemzőit.

Ahhoz, hogy megkapjuk azt a pontot, ahova az avatárunk elmozdul, szükségünk lesz a csempe x és y értékeire, és meg kell kapnunk a 'kezdő x' és 'kezdő y' attribútum értékeket a 'Rács' címkénkhez. Ezen értékek alapján adjuk hozzá a 'legközelebbi csempe' x értékét a 'kezdő x' értékhez, és ugyanígy a y értékek esetében is. Ezek az összeadott értékek a cél x és y pontok, ahová az avatárunk mozogni fog.

Az elmozdulás előtt állítsuk be az avatárunk 'korábbi csempe' értékét a jelenlegi 'csempe' attribútumának értékével. Ezt az 'csempe' értéket a korábbi csomagokból kaphatjuk meg. Ezután az avatárunkot a célpontokhoz mozgassuk 0.2 tartammal.

A 'Pontohoz mozgás' viselkedés befejezése után beállítjuk az avatáruk 'csempe' attribútumának értékét a 'legközelebbi csempe' tömb értékével. Ha a 'legközelebbi csempe' tömb értéke nem egyenlő a 'célcsempe' tulajdonsággal, akkor végrehajtjuk a 'Útvonalkereső' csomagot, tehát ismételjük az egész csomagot. A 'célcsempe' attribútum értéke a korábbi csomagból információval megkapható.

Ha megnyomjuk bármely kék csempét, és az avatárunk a rácsunkban megjelenik, az 'Útvonalkereső' csomag végrehajtódik. Ez elindítja az avatár mozgatását csempről csempre.

Következtetés

Ebben a bemutatóban megtanultuk, hogyan készítsünk egy objektumra alapuló útvonalkereső tevékenységet egy tömb segítségével, amelyet 'Rács'-nak nevezünk, ami tárolja az információt, hogy az adott csempe foglalt-e vagy sem. Bővítheti ezt az ötletet, hogy objektumok id-jait használja információtárolóként, nem csupán számokat a 'Rács' tömbben. Ez megbízhatóbb információt adhat, amelyet felhasználhatunk az útvonalkereséseknél. Például megkaphatjuk az objektum id attribútumait, hogy megtudjuk, hogy életben van-e vagy sem, és hogy léphetünk-e a csempéjére vagy sem.

Ez a bemutató csak az útvonalkeresés alapötletet szolgáltatta. Egy hátránya, hogy nem hoz létre a lehető legrövidebb utat a cél csempe felé, és csak a jelenlegi szomszédos csempéit ellenőrzi. Ez mozgási ciklushoz vezethet, amely nem visz sehová.

Ez azonban megoldható úgy, hogy bővítjük az útvonalkereső algoritmusunkat. Ezt megtehetjük úgy, hogy átirányítjuk a begyűjtött szomszédos csempéket, hogy megtalálják a szomszédos csempéket is, amíg el nem érjük a célcsempénket. Minden található legközelebbi szomszédos csempe hozzáadásra kerül egy listához. Az végtelen ciklus elkerülésére adjon hozzá egy feltételt, hogy ha az a szomszédos csempe már ellenőrzve van, akkor ez a csempe nem kerül hozzáadásra a listához. Szintén tegyen korlátot az iterációs számra, hogy elkerülje a célcsempe által okozott végtelen ciklust, ha az túl messze van, vagy nem található. Amint az iteráció megtalálja a célcsempét, kilépünk abból az iterációból, és elkezdjük az avatárunkat a csempről csempe mozgását a csempe listán keresztül.</p>