Bağlantılı yollara sahip prosedürel 2D harita için algoritma


26

Çözülecek sorun: Tüm odaların bağlı olduğu karo tabanlı bir oyun için rastgele bir 2B zindan haritası oluşturun.

Şu anda sahip olduğumdan daha iyi çözümler arıyorum.

Mevcut çözümüm iki algoritmayı çalıştırmam. Birincisi odalarıyla zindan üretir. İkincisi, tüm odaların birbirine bağlı olduğundan emin olun. Başka ne tür çözümler olabileceğini merak ediyorum. Daha hızlı ve / veya daha kolay vb. Hız gerçekten bir endişe değildir, ancak hız gerçek bir ücret ödemeden kazanılabilirse, bu iyi bir şeydir. Daha önemlisi, ben ve okuyan başkalarının soruna yaklaşmanın ve çözmenin farklı yollarını öğrenebilirim.

Benim şimdiki uygulamam. Odaların şu anda herhangi bir 2, 3 veya 4 yönünde çıkış veya çıkışı yoktur.

Zindan odalarının oluşturulması

Kurulum: Geçerli odayı sol üst odaya ayarlayın.

  1. Oda için geçerli bir oda tipi edinin (burada geçerli oda tipi, zindandan çıkışı olmayan ve odanın çıkışları ile odanın solundaki odanın çıkışları ile eşleşen bir çıkış tipidir. aşağıdaki 2. adımdan dolayı kaldı).
  2. Odayı yere koy ve x koordinatını bir adım ilerlet. X koordinatı zindan genişliğini aşarsa, x koordinatını 0 olarak ayarlayın ve y koordinatını bir adım ilerletin. Y koordinatı zindan yüksekliğini aşarsa, biz yapılır.
  3. # 1'den tekrarlayın.

Daha sonra bütün odaların bağlı olup olmadığını kontrol ediyorum. Eğer hepsi birbirine bağlı değilse, zindan yerleşimi açısından, seksi olmayan fakat kesinlikle iyi bir şekilde, odaların içinden geçen ve onları değiştirecek şekilde değiştiren ikinci bir algoritma kullanıyorum. bağlı olmak.

Tüm odaların bağlı olup olmadığını kontrol etme

Kurulum: Yolları temsil eden 2 boyutlu bir tamsayı haritası oluşturun ve girişleri "işlenmemiş" (henüz geçilmemiş) bir değere göre ilklendirin, -1. Geçerli yolu takip eden 1 olan bir başlangıç ​​yolu dizini tamsayısı ayarlayın. Geçerli odayı kontrol etmek için bir oda yığınına ekleyerek sol üst odaya ayarlayın.

  1. Yığın denetlenecek odalar içeriyorsa, odanın yol dizinini geçerli yol dizinine ayarlayın. Yığın oda içermiyorsa, yol dizinini artırın ve henüz işlenmemiş bir oda elde edinceye kadar, satır sütun satır sütun ilerleterek oda elde etmeye çalışın. Eğer yer bulunamazsa işimiz biter.
  2. Odanın sola doğru çıkışı olup olmadığını kontrol edin. Zaten orada değilse, sol odayı yığına eklerse.
  3. Aşağı, sağ ve üst yönler için 2. adımı tekrarlayın (odaların üst yöne doğru başlayarak saat yönünde döndürüldüğü anlamına gelen bir yığın kullanıyoruz).
  4. 1. adımdan itibaren tekrarlayın.
  5. Yol endeksleri sayısı birden fazla ise, bağlantısı kesilmiş odalar vardır.

Bağlantısız odalar varsa, o zaman odaları yol dizinine göre gruplarım, en büyük yolun dizinini alın ve diğer tüm odaları bu odalara bağlayın. Bu devam etmekte olan bir çalışma, ancak (şimdiki "brutish") planım, bir oda grubundaki her odadan geçiyor (ilk hariç), büyük grup odasına yatay veya dikey bir yol olup olmadığını kontrol etmek ve öyleyse, aralarında odaları enjekte ederek / güncelleyerek yatay / dikey bir yol oluşturun. Durulayın ve tekrarlayın. Çirkin, evet, ama görsel desen açısından farkedilmeyecek bir şey bu yüzden bu anlamda çalışır.


1
PCG wiki'de "Dungeon Generation" adlı kullanıcıyı kontrol ettiniz mi? Sorularınıza cevap veriyor mu?
congusbongus

@congusbongus Faydalı bir kesin okuma. Bu sayfaya bağlı olan o donjon jeneratörü harika. Teşekkürler.
user1323245

Yanıtlar:


33

Orada gördüğüm en iyi ve en çok kullanılan algoritmalardan biri, Binary Space Partitioning kullanarak zindan üretiyor.

Okuduğum en iyi genel açıklama , Doryen Chronicles of Chronicles (yedekleme amacıyla eklenmiş) 'te bulunandır .

Aynı konuyla ilgili diğer iki öğreticinin kodu ile birlikte bulunabilir.


BSP ağacının oluşturulması

Duvar hücreleriyle dolu dikdörtgen bir zindan ile başlıyoruz. Her zindan yaklaşık bir oda büyüklüğüne gelinceye kadar bu zindanı tekrarlı olarak böleceğiz. Zindan bölmesi bu işlemi kullanır:

  • Rasgele bir yön seçin: yatay veya dikey bölme
  • Rasgele bir konum seçin (dikey için x, yatay için y)
  • Zindanı iki zindana böl

görüntü tanımını buraya girin

Şimdi iki alt zindan A ve B'ye sahibiz. Aynı işlemi ikisine de uygulayabiliriz.

görüntü tanımını buraya girin

Bölme pozisyonunu seçerken, zindan sınırına çok yakın olmamaya özen göstermeliyiz. Oluşturulan her alt zindanın içine bir oda koymalıyız. En düşük zindanlar, oluşturmak istediğimiz odaların büyüklüğünü alana kadar tekrar ediyoruz.

görüntü tanımını buraya girin

Zindan inşa

Şimdi ağacın her yaprağına rastgele büyüklükte bir oda yaratıyoruz. Tabii ki, oda ilgili alt zindanın içinde tutulmalıdır. BSP ağacı sayesinde üst üste binen iki odamız olamaz.

görüntü tanımını buraya girin

Koridorları inşa etmek için ağacın bütün yapraklarını geçerek her bir yaprağı kız kardeşine bağlarız. İki oda yüz yüze duvarlara sahipse, düz bir koridor kullanabiliriz. Aksi takdirde, Z şeklinde bir koridor kullanmak zorundayız.

görüntü tanımını buraya girin

Şimdi ağaçta bir seviye yükseliyoruz ve baba alt bölgeleri için süreci tekrar ediyoruz. Şimdi iki alt bölgeyi iki oda arasındaki bir bağlantıyla veya bir koridor ile bir oda veya iki koridor arasında bağlayabiliriz.

görüntü tanımını buraya girin

İlk iki zindan A ve B'yi birbirine bağlayana dek işlemi tekrar ediyoruz.

görüntü tanımını buraya girin


Bu tekniğin asla döngü yaratmayacağı hiçbir şeye değmez, ancak daha rastgele koridorlar eklemeden bunun bir yolu olup olmadığından emin değilim. Yine de çok iyi bir cevap, +1
Vality

Bu umut verici bir başlangıç. Sadece ona birkaç ilmek eklemek için bir yol bulmaya ihtiyacım var, fakat şu anda bulunduğum yolda devam etmekten çok bu problem üzerinde çalışmayı tercih ediyorum. Teşekkürler.
user1323245

2
Güzel ! Kimlikle ilgileniyordum, bu yüzden küçük bir girişimde bulundum. Rasgele kullanırken dikkatli olmanız gerekir, aksi takdirde çok garip sonuçlar takip eder. Ve yinelenen bölünme sırasında koridorların doğru kullanılmaması gerekip gerekmediğini merak ediyorum, çünkü koridordan ağaçtan kolayca çıkmanın kolay yolunu göremiyorum. Kemanla
GameAlchemist

Bunu geniş ortamlarda tekrarlanabilir ekili prosedürlerde biraz sorunlu bulurken. Muhtemelen tüm seviyenizi bir kerede üretebilmenizi sağlayan bu tür bir nesil için şimdiye kadar gördüğüm en iyi yöntemlerden biri. Bunu +
O Evsiz Adam

4

BSP yöntemi görünüşte zindanları üretmek için en popüler yöntemdir, ancak yalnızca bir tane değil.

Tamamlanması için benim için çalışan jeneratörü açıklayacağım . Ben bu konuda okumak nerede ben sadece benim icadım olmadığını söylerim ben hatırlamıyorum itiraf etmeliyim (bir eski yazı ile Jamis Buck çok tanıdık geliyor).

Odaları ile bir labirent

Temel fikir, bir zindanın bir çeşit odaya sahip bir labirent olduğu yönünde. Bu algoritma için ilk adım, bir labirent üretmektir :

Eller algoritmasının bir varyasyonu ile üretilen labirent

Bir sonraki adım seyrek yapmaktır (çıkmazları çıkarın):

Seyrek olun: çıkmazları çıkarın

3 numaralı adım, bazı döngüler eklemek ( mükemmel olmayan bir hale getirmek ) ancak görüntüyü atlayacağım çünkü çok az farkedilebilir (mükemmel bir labirente ihtiyacım yoktu, bu yüzden labirent oluşturma algoritmasında birkaç kısayol kullandım. bu noktada döngüler vardı).

Sonra, 4. adım için, izole edilmiş hücreleri çıkarmamız gerekir:

İzole hücreleri çıkarın

Bu noktada koridorları bitirdik ve oda eklemeye hazırız. Bunun için aşağıdakileri yaparız:

  1. Bir oda grubu oluşturun (genişlik ve yükseklik)
  2. Her oda için mümkün olan bütün yerleri tekrar sıralıyoruz ve en iyi yere karar veriyoruz.
    • En iyi konum, koşullara bir ağırlık eklenerek hesaplanır (bir koridora bitişik gibi).
  3. Odaları yerleştiriyoruz.

Şimdiye kadar, zindanımız şöyle görünecek: Oda eklendi

Son adım, süslemeler eklemektir.

Kapı ve oda numaralarını çizin

Bazı son düşünceler

  • Eller Algoritmasının soyulmuş bir versiyonunu kullandım .
  • Farklı labirent algoritmaları farklı dokulara neden olabilir. Başka bir algoritma tercih edebilirsiniz. Örneğin, aşağıdaki resimde "İkili Ağaç" (diyagonal önyargı) ve "Özyinelemeli Bölünme" (uzun koridorlar) algoritmalarının bir varyasyonundan kaynaklanan farklı dokular gösterilmektedir : İkili Ağaç vs sahte-Özyinelemeli Bölüm

2
İyi şeyler. Farklı seviyeler için farklı algoritmalar kullanmak oyunu daha da çok yönlü hale getirebileceğinden, bunu yapmanın farklı yollarını arıyorum.
user1323245
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.