Izgara Tabanlı Yol Bulma
Bu eğitimde, bir 2 boyutlu dizi ızgarasına dayalı bir yol bulma simülasyonu oluşturacağız. Bu, oyunlarımıza yol bulma etkinlikleri oluşturma konusunda temel bir fikir verecektir. Izgarayı, komutlarımızla o alanın üzerinde hareket edebilen, boş kare nesneleri karolar olarak ve yuvarlak bir nesneyi avatarımız olarak görselleştireceğiz.
I. Nesnelerin ayarlanması
Projemizde sadece dört nesne kullanacağız. Yeşil avatarımız, mavi kare, beyaz engel ve ızgaramızı kurmak ve görselleştirmek için ızgara etiketi.
Avatar
Avatarımız, %50 x ve y ölçeğine sahip boş bir nesnedir. Çarpışma şeklinin yuvarlak olarak ayarlanmış olmasını sağlayın, böylece aşağıdaki resimdeki gibi görünecektir. Bu nesneden üç önceden tanımlı niteliği olacaktır: ızgaradaki karo, önceki karo ve hedef karo. Bu niteliklerin varsayılan değerlerini sıfıra ayarlayın, böylece daha sonra bunları almak istediğimizde null değeri almazlar.
Karo Nesnesi
Izgaramızda karoları görselleştirmek için kullanılacak başka bir boş nesne oluşturun. Ölçeği de %50'dir ve yalnızca bir önceden tanımlı niteliği vardır: karo üzerindedir. Bu değeri de sıfıra ayarlayın.
Engel Nesnesi
Izgaramızda blokaj görevi görecek başka bir boş nesne oluşturun. Bu, %40 ölçeğine sahip beyaz bir boş nesnedir. Avatarımız, üzerinde bir engel olan bir karoya geçemeyecek.
Izgara Etiketi
Bu, ızgaramızın kurulması ve görselleştirilmesini sağlayacak davranışlara sahip bir etikettir. Önceden tanımlı nitelikleri vardır: 4 değerine sahip başlangıç x ve 3 değerine sahip başlangıç y. Bu değerler, karolarımızı yerleştirirken ızgaramızın düzgün bir şekilde ortalanması için kullanılacak ofsetlerdir.
Avatar/Karo Önceden Tanımlanmış Nitelikler:
Burada bir karoyu, ızgaramızda bir x ve y değerine sahip 2 boyutlu bir dizi olarak tanımlıyoruz.
- karo üzerinde - bu, nesnemizin ızgarada şu anda bulunduğu karo değeridir
- önceki karo - avatarımız tarafından daha önce geçilen bir karo
- hedef karo - avatarımızın gideceği karo
II. Izgarayı Kurma
Izgara etiketinin içinde, 2D dizimizi ve ızgaramızın yerleştirilmesini tanımlayacağız. Bu nesnede iki ana anahtar nokta vardır: diziyi ayarlamak ve diziyi görselleştirmek. Öncelikle dizi seti paketini yapalım.
Diziyi Ayarlamak - paket
Öncelikle 'Grid' adında boş bir dizi oluşturun. Bu dizi, 2 boyutlu dizimizi içerecektir. 24 değerine sahip bir 'x satır sayısı' adında bir kutu içeriğimiz olacak ve 18 boş değere sahip başka bir boş dizi 'y satır' adında olacaktır.
Paketimizdeki ilk davranış, 'x satır sayısı' kadar tekrarlanan bir döngüdür. Bu döngünün her adımında, 'Grid dizisi'ne boş bir y satırı ekleyeceğiz. Bu, 24x18 boyutunda bir dizi oluşturan dizi içinde bir dizi oluşturacaktır.
Dikkat edin ki, bu paketimizin başlangıcında otomatik olarak çalışmasını engellemek için pasif bir yorum bağlantısı oluşturmuşuz. Kök bir davranış, herhangi bir olayla tetiklenmeyen ve arayüzde açıkça yerleştirilen bir davranıştır.
Izgarayı Görselleştirme - paket
Burada yapacağımız ana şey, 'Grid dizisi'ndeki her değere geçmek ve bir karo nesnesi oluşturmak. Ayrıca döngümüzde, karo nesnesinin üzerinde beyaz bir engel oluşturulmasına izin verecek bir koşul da ekleyeceğiz.
Öncelikle 'y satır dizimizde' dizi sayısını almak, bu nesnenin 'başlangıç x' nitelik değerini ve 'başlangıç y' değerini alıyoruz.
Bir döngü oluşturun, 'x satır sayısı' kadar tekrar eden ve bu döngünün her adımında o döngünün indeks değerini ve 'başlangıç x' nitelik değerini toplayacağız. Bu, daha sonra yerleştirdiğimiz karoların kesin x konumunu kullanacağımız mutlak bir x konumu ile sonuçlanır. Daha sonra 'y satırı döngüsü' 'y satır sayısı' kadar tekrarlanan bir döngüdür. Bu döngünün her adımında, o döngünün indeks değerini ve 'başlangıç y' nitelik değerini toplamamız, şimdi mutlak bir y konumuyla sonuçlanır.
Y satır döngüsünün altında eklenen değerlerden sonra mavi nesneyi oluşturuyoruz. Bunun yaşam nesnelerinin sayısını 999 olarak ayarlayın, çünkü ızgamız için birçok gereksinim duyacağız, ve ayrıca süresi 0 olanlarla. Daha sonra o oluşturulan nesneyi, mavi döngüdeki 'eklenen değerlerden' bir x noktasına ve y noktasına yerleştiriyoruz.
Ardından, yalnızca yer tutucu olarak kullanacağımız 2 boş değere sahip 'On tile' adında bir dizi ekliyoruz. Karo nesnesini hareket ettirdikten sonra, 'On tile' dizisini değiştirip indeks 0'daki değerini 'x satır döngüsünün' değeri ile değiştiriyoruz. Daha sonra, başka bir dizi değişikliği ekleyin, dizinin indeks 1'indeki değeri 'y satır döngüsü' indeksinin değeriyle değiştirin. Bu, nesnemizin 'şu anda bulunduğu karo' niteliği olarak kullanacağı ızgarda x ve y koordinatıdır.
Şimdi, oluşturulan nesnenin 'on tile' niteliğini, 'On tile - dizi' değerinin dinamik bir anahtarıyla ayarlayın.
Y satır döngüsünün altında, beyaz nesne engel oluşturma koşulu vardır. Bu paketimizi yürütmek için 5 sayısından 2'si gerçekleştirme şansımız olacak, bu da ızgaramızın rastgeleliğini artıracaktır. Ardından x ve y koordinatına 'Grid' dizisinde 1 değeri atayarak bayrak oluşturuyoruz.
Öncelikle 1 ile 5 arasında rastgele bir sayı oluşturun. Bu sayı 2 veya daha az ise, engeli oluşturan 'set its #Alive' nesnelerini 999 yapın ve bu nesneyi daha önce oluşturduğumuz mavi karonun aynı noktasına taşımak için süresini 0 yapın.
Daha sonra bu koordinatın engel ile kaplandığını kaydetmek için, eğer oluşturulmuşsa. Yüksekliği 1 olan bayrak değerini işaretleyerek gerçekleştirin. Öncelikle 'Grid' dizisinin 'x satır döngüsü'ndeki değerini alın. Bu değer, bir 'y satırı' dizisi verecektir. Bu y satırını değiştirip değerini 'y satır döngüsü'ndeki indeks ile değiştirerek 1, işaretli değeri kullanacağız. Bu değer değişikliği yalnızca o değer için geçerli olduğundan, 'Grid' dizisini de değiştirmemiz gerekiyor. 'Grid' dizisindeki x satır döngüsü indeksine 'değiştirilen y satır' dizisine bir değer ile değiştirin.
Oynandığında, bu tür bir biçime sahip olmalıdır.
III. Karo Basma
Izgarayla etkileşime geçebilmek için, bir mavi karo üzerine basıldığı her seferde bir paket davranışa ihtiyacımız var. İlk basma, avatarımızın ızgaramızda görünmesine yol açacak, ve sonraki her basış, yol bulma işlemini başlatacaktır.
Mavi nesnenin içinde, önceki karo niteliğini sıfırlamak, üstteki nitelik değerini ayarlamak ve renk animasyonunu görselleştirmek için üç ana noktaya sahip bir davranış paketi vardır.
Öncelikle karo nesnesinin 'on tile' niteliğini alın. Avatarımızın 'önceki tile' niteliğini 0 olarak ayarlayın. Avatarımızın öncelikle 'önceki tile' geri dönmesini önlemek için, her karo baskısında 'önceki tile' sıfırlıyoruz.
Sonra, avatarımızın 'on tile' niteliğini alıyoruz. İlk if koşulu, 'on tile' değerinin sıfıra eşit olup olmadığını kontrol eder. Bu, avatarın henüz görünmemiş olması anlamına gelir, bu yüzden bu doğru olur. Doğruysa, avatarımızın 'on tile' niteliğini, karo nesnesinin 'on tile' niteliği ile ayarlayacağız. Daha sonra avatarımızın konumunu almak için karo nesnesinin konumunu alarak x ve y değerlerini o noktaya yönlendireceğiz, süresi de 0 olacak.
'On tile' değeri sıfıra eşit değilse, avatarımızın 'hedef tile' niteliğini, karo nesnesinin 'on tile' niteliği ile ayarlayacağız. Bu, avatarımızın ızgarada zaten bulunduğu anlamına gelir, böylece, 'yol bulma' davranışı paketini yürütmeye başlayabiliriz. Henüz bu davranışa sahip değiliz ama daha sonra, bu eğitimin ilerleyen kısımlarında 'yol bulma' paketini düzenleyeceğiz.
Artık avatarımızı ızgaraya uygun bir şekilde ayarladık, basma olayını görselleştirmeniz gerek. İlk önce, kök davranışı 'rengi alarak' orijinal rengini alın. Basma olayından sonra, karo nesnesinin rengini 0 süreyle siyah yapın ve sonra tekrar orijinal değerine 0.2 süreyle ayarlayın.
Mavi bir karoya basmak, bunun sonucunu vermelidir.
IV. Yol Bulma Paketini Yürütme
Bu eğitimimizdeki son bölümde, avatarımızın varış noktasına ulaşmak için alabileceği en yakın karoyu bulmamızı sağlayacak algoritmayı yapacağız. Bu paket, avatarımız ızgaramızda her adım attığında sürekli yürütülecektir.
Algoritmayı avatar nesnemizde ayarlayacak ve üç ana noktaya sahip olacaktır: bitişik karoları bulmak, en yakın bitişik karoyu bulmak ve o bitişik karoya hareket etmek.
Bitişik karo bulma
Bu kısımda, avatarımızın geçebileceği tüm bitişik karoları topluyoruz. Dört yönlü bitişik karolarını kontrol ederiz ve bu karoların üzerinde bir engel olup olmadığını veya daha önce basılı olup olmadığını kontrol ederiz.
Öncelikle, 'Bitişik karolar' dizimizi ekliyoruz. İçinde iki boş değer olan bir 'Yön' dizisi ve her biri iki değere sahip dört yönlü dizi; N (0,1), S (0,-1), E (1,0), W (-1,0).
Paketimizdeki ilk davranış, bitişik karolarımızı temizlemektir. Bu paketi sürekli tekrar edileceği için, her seferinde topladığımız 'bitişik karolar' dizimizin sıfırlanması gerekecek. Sonraki dört davranış, 'Yön' dizisine değişikliklerdir. Dört kez 'yön' dizisini yönlü dizilerle ayarlıyoruz ve ardından aşağıdaki paketi yürütüyoruz. Farklı 'Yön' dizisi değerleri ile her seferinde farklı bir döngü oluşturmak içindir.
Artık yönlerimize sahipsak, yalnızca bunların x ve y değerlerini avatarımızın 'on tile' niteliği ile birleştirmemiz yeterlidir. Sonra, 'Grid' dizisinde o noktayı almak için 'hedef' değerimizi alabileceğiz. Bu, o karonun üzerinde bir engel olup olmadığını bildirecektir.
'Yön x', 'Yön' dizisinin 0 indeks'indeki değerdir, 'get on tile' x, 'gelen on tile'ın 0 indeks değeridir. Hedef x ise 'yön x' ile 'get on tile x' toplamını verecektir. Aynı şekilde y değerlerimiz için de hedef indeksi 1 ile aynı işlemleri yapılır.
'Hedef y satırı', 'Target x' indeksi ile 'Grid' dizisinin array değeridir. Ve sonra 'Target y satırındaki hedef indeksi', 'Target y row' dizisinin 'Target y' indeksindeki değerini alacağız. Bu, ızgaramızda o koordinatı öğrenerek engel olup olamayacağını verir.
Eğer 'Target y row' 'Target index in y row' değeri 1 ise, o hedef karo engellenmiş demektir. Ancak bu değer 1'e eşit değilse, o zaman pakete devam edebiliriz.
'Target x' ve 'y' değerleri koşulumuzu geçerse, yeni bir boş karo dizisi olan 'Yeni bitişik karo' dizisini ekliyoruz. Bu, hedef x ve y'yi bir karo dizisi olarak depolayacaktır. Hedef x'i 'Yeni bitişik karo'nın indeks 0'ına ve hedef y'yi indeks 1'ine atıyoruz.
Şimdi avatarımızın 'önceki dizi' niteliğini alıyoruz. Eğer 'önceki tile', 'yeni bitişik gerçekten' eşit değilse, bu, yeni karonun daha önce geçilmediği anlamına gelir. O zaman 'Yeni Bitişli Karo' 'Bitişik Karo' dizimize eklemek için güvenle ekleme yapabiliriz. 'Önceki kaidenin' değerini her yeniden avatarı başka bir karoya taşıdığımızda ayarlayacağız.
"Bu paketi, avatarınızın çapraz yönlere kaymasına olanak tanıyacak 8 yönlü diziler oluşturarak genişletebilirsiniz."
En yakın bitişik karonun bulunması
Artık güvenilir bitişik karolarımızı topladığımıza göre, yalnızca avatarımızın hedef karosuna en yakın olan bitişik karoyu almalıyız. Hesaplamayı hedef karomuzun x ve y değerleri ile bitişik karoların x ve y değerlerini kullanarak yapacağız.
Bu pakette iki ana anahtar nokta vardır: hesaplama için değişkenlerin başlatılması ve bir döngü içinde karo mesafelerinin hesaplanması.
a. Değişkenlerin Başlatılması
Öncelikle, bitişik karoların dizi sayısını alırız. Daha sonra avatarımızın 'hedef karo' niteliğini alır ve x ile y değerlerini alırız. "Min distance" ve "Hedef karo indeksi" adında iki adet yeni kutu ekliyoruz. 'Min mesafeyi' 9999 değerine, 'hedef karo indeksini' ise 0 değerine ayarlıyoruz. Min mesafesi yüksek bir değere ayarlanmıştır çünkü başlangıçtan elde edilen en az mesafeyi bulmamız gerekiyor. Diğer taraftan hedef karo indeksi, avatarın 'hedef karo'suna en az mesafeye sahip olan 'Bitişik Karo' dizisindeki referans indeksimizdir.
Buradaki ana hedefimiz, 'Bitişik Karo' dizisindeki en yakın hedef karonun indeksini almaktır.
b. Karo mesafelerinin Hesaplanması
Bu pakette, hesaplamayı 'bitişik karolar sayısı' kadar tekrar eden bir döngü içerisinde gerçekleştireceğiz. Döngü, o döngü içindeki indeksin değerini alarak 'Bitişik Karolar' dizisindeki karo değerini alacaktır.
O bitişik karonun x ve y değerlerini alırız, ardından hedef karo ile bitişik karo arasındaki mesafeyi hesaplarız, bu formülü kullanarak:
mesafe = sqrt((x2 - x1)^2+(y2 - y1)^2)
x1 = Hedef x
x2 = Bitişik x
y1 = Hedef y
y2 = Bitişik y
Öncelikle x ve y değerlerini birbirinden çıkarırız, kendi kendine çarparız ki üs değerlerini almış olalım, bu değerleri toplarız ve sonra toplam değerlerin karekökünü alırız. Böylece mesafe değerini elde ederiz.
Mesafe değeri 'Min distance' kutu değerinden küçükse, 'hedef karo indeksi' o anki döngü indeksinin değerine ayarlanır, bu da 'Bitişik Karolar' dizisinde elde edilen karo indeksini belirtir. 'Min mesafeyi' kutu değerini de 'Mesafe' değeri ile ayarlıyoruz, böylece sonraki döngüde karşılaştırabiliriz.
Döngünün sonuna geldiğimizde, her bir bitişik karomuzu karşılaştırmış olduk ve 'hedef karo'ya en yakın olan bitişik karonun indeks değerini elde ettik.
Bitişik karoya hareket etme
Bunun eğitimimizin sonunda, avatarımızı en yakın bitişik karoya hareket ettireceğiz ve zaten 'hedef karo' ya doğru hareket etmediğimiz takdirde tüm yol bulma paketini tekrar yürüteceğiz.
İlk olarak, 'Bitişik Karo Sayımızın' 0'dan büyük olup olmadığını kontrol ediyoruz. Bu, en azında güvenilir bir bitişik karoya duyduğumuz güven olması gerektiği anlamına gelir.
Ardından, önceki paketimizdeki 'hedef karo indeksi' değerini kullanarak 'En Yakın Karo' değerini elde ediyoruz.
Avatarımızın hareket etmesi için belirli bir noktaya ulaşmasını sağlamak için, her iki bitişik kare için de x ve y değerlerini alacağız, ayrıca 'Grid' etiketimizdeki 'başlangıç x' ve 'başlangıç y' niteliğini de alacağız. En yakın karo ve başlangıç x değerlerini, ve aynı şekilde y değerlerini de topluyoruz. Bunlar, avatarımızın hareket edeceği hedef x ve y noktalarıdır.
O noktaya hareket etmeden önce, avatarımızın 'öner kaydını', 'on tile' niteliğinin değerine ayarlıyoruz. Bu 'on tile' değerine önceki paketlerden erişebiliriz. Ardından avatarımızı hedef noktalarımıza 0.2 süresiyle hareket ettiriyoruz.
'Hedefe hareket' eylemi tamamlandıktan sonra, avatarımızın 'on tile' niteliğini, 'en yakın karo' dizisinin değerine ayarlıyoruz. Eğer 'en yakın karo' dizisi, 'hedef karo' değerine eşit değilse, 'Yol Bulma' paketini yürüteceğiz ve böylelikle bütün paketi tekrar gerçekleştirmiş olacağız. 'Hedef karo' niteliği tüm paktı bulmamıza yardımcı olmaktadır.
Mavi bir karoya tıkladığınızda ve ardından avatarın ızgarasında görünmesiyle birlikte, 'Yol Bulma' paketi yürütülecektir. Bu, avatarın karodan karoya hareketini başlatacaktır.
Sonuç
Bu eğitimde, 'ızgara' adını verdiğimiz bir dizi kullanarak bir nesne yol bulma etkinliği oluşturmayı öğrendik, ki bu, o karonun dolu olup olmadığını belirtmek için kullanılır. Bu fikri genişletmek, nesne kimliklerini nesneleri depolama bilgisi yerine sadece sayısı yerine kullanmak olabilir ve böylelikle, yol bulma işlemi sırasında kullanılacak daha güvenilir bilgilere ulaşabiliriz. Örneğin, bu nesne kimliği ile o nesnenin canlı olup olmadığını ya da karoya basıp basamayacağımızı anlayabiliyoruz.
Bu eğitim sadece yol bulma işleminin temel fikrini içermektedir. Bu konudaki bir dezavantaj, mümkün olan en kısa yolun oluşturulmaması ve yalnızca mevcut bitişik karolar üzerinde kontrol yapılmasıdır. Bu, bir hareket döngüsü oluşturabilir ve bu nedenle hedefine ulaşamaz.
Ancak bu sorun, yol bulma algoritmamızı genişleterek çözülebilir. Bunun için, yeniden elde ettiğimiz bitişik karolar üzerinde tekrarlama yaparak hedef karoyu bulana kadar devam edebiliriz. Her yeni bulunan en yakın bitişik karo bir listeye eklenir. Sonsuz bir döngüyü önlemek için, o bitişik kara daha önce kontrol edilmişse, o kara, listemize eklenmeyecektir. Ayrıca, bir sebep olan hedef karo çok uzaktaysa veya bulunamıyorsa, yine de sonsuz bir döngüyü önlemek için yine de bir max değer ekleyin. O iterasyon hedef karoyu bulduğunda, bu iterasyonu durdurur ve avatarı karoların kaynağından hareket etmeye başlarız.

