Birçok akın düşmanı engellerin etrafında etkili bir şekilde bulma


20

Oyunumun düşmanları için yol bulmayı geliştirmeye çalışıyorum. Şu anda, kendileri ve oyuncular arasındaki açıyı hesaplayıp bu yönde hareket ederek oyuncunun tam konumuna doğru sürekli hareket ediyorlar. Ayrıca düşmanların üst üste istiflenmesini önleyen bir akın algoritması var, bu yüzden birbirlerinden geçmektense gruplara dönüşecekler.

Ancak, şimdi kiremit tabanlı bir harita eklediğime göre, örneğin engeller ve duvarlar etrafında da yol alabilmek için düşmanlara ihtiyacım var. Başlangıçta akın algoritması, duvarları ve engelleri uzaklaşmak için nesneler olarak düşünecek şekilde "yürüyemeyen" fayanslara ayırma değeri eklemeyi denedim. İlk testim düşmanlara, yürünemez fayansların olmadığı görünmez bir "duvara" çarptığını gösterdi, ancak bir nedenden dolayı vurdular ve spazzing yapmaya başladılar.

A * kullanarak oyuncuya bir yol hesaplamak ve sonra topaklanmayı önlemek için akın algoritmasını kullanmak için çok ağır bir performans olup olmadığını merak ediyordum. Başlangıçta oyunum dalga tabanlı bir nişancı olacaktı, ama bunun yerine Hotline Miami damarında seviye tabanlı yapmaya karar verdim, bu yüzden ara sıra kalabalıkla daha az düşmana sahip olacağım ve daha güçlü.

Bu uygun bir çözüm müdür? Oyun motorum olarak Slick2D ile Java kullanıyorum. Yoksa her iki sorunu da ele alan daha iyi bir çözüm / algoritma var mı?


7
Düzenlemede açıkladığım gibi, "bu çok ağır mı?", Profilinize sormak için bir sorudur, çünkü uygulamanıza, hedef donanıma, performans bütçesine ve oyununuzun bağlamına bağlı olacaktır - siz ve profil oluşturucunuzun bildiği her şey ama yabancılarla değil. Sürülerin yol bulmasını verimli bir şekilde elde etmek istiyorsanız, buna yardımcı olacak stratejiler önerebiliriz, ancak ihtiyaçlarınız için yeterince verimli olanı yalnızca kendi profil oluşturma yanıtlayabilir. Belirli bir performans sorununu profil olarak belirlerseniz ve bu sorunu nasıl çözeceğinizi bulmanıza yardımcı olabiliriz.
DMGregory

1
Bunları nasıl uyguladığınız performansı etkiler. Örneğin, sadece liderler üzerinde A * çalıştırmak ve takipçileri için akınlara güvenmek.
Pikalek

Oyununuz öncelikle bu düşmanlarla savaşmaya dayanıyorsa, aldığınız algoritmanın oyunun nasıl hissettiği üzerinde büyük bir etkisi olacaktır. Bu yüzden farklı yaklaşımları denemelisiniz, örneğin düşmanlar oyuncunun seviyesini ve pozisyonunu her zaman mükemmel bir şekilde biliyor ve onu her şeyi bilen bir AI tarafından yönetildiği gibi takip ediyorlar mı? - diğer yaklaşımlar, düşmanların oyuncunun ses çıkardığı genel yönde ve sadece ona doğru doğrudan görüş hattında koşmasına izin vermek veya oyuncunun bulunduğu diğer düşmanları bağırıp bilgilendirmek olabilir ...
Falco

@Falco Oyun artık dalga tabanlı olmadığından ve seviye tabanlı olacağından ve düşmanlar zombiler olduğundan ... Bunu görmeyi ya da sizi bulmaları için onlara ses çıkarmanız gerekiyordu. Gürültülü bir silah kullanırsan? Bir menzil içinde bir ses yayar ve yayılan sesin konumuna doğru menzil yolundaki tüm düşmanlar ve daha sonra bu alanın etrafında rastgele yol alır.
Darin Beaudreau

Yanıtlar:


49

Bu, Akış Alanları için bir kullanım durumu gibi görünür.

Bu teknikte, oyuncu nesnelerinizden dışarı doğru tek bir yol bulma sorgusu gerçekleştirir ve karşılaştığınız her hücreyi, ona ulaştığınız hücre ile işaretlersiniz.

Tüm karolarınız / kenarlarınız eşit geçiş maliyetine sahipse, bunun için önce basit bir genişlik araması kullanabilirsiniz. Aksi takdirde, Dijkstra'nın algoritması (hedefsiz / sezgisel olmayan A * gibi) işe yarar.

Bu bir akış alanı oluşturur: her hücreyi bir sonraki adımla o konumdan en yakın oyuncu nesnesine doğru ilişkilendiren bir arama tablosu.

Artık düşmanlarınız, her biri kendi yol bulma sorgusu yapmadan en yakın oyuncu nesnesine en kısa engellerden kaçınma yolundaki bir sonraki adımı bulmak için akış alanındaki mevcut konumlarını arayabilir.

Bu, sürüde daha fazla düşmana sahip olarak daha iyi ölçeklenir ve daha iyi olur. Tek bir düşman için A * 'dan daha pahalıdır, çünkü haritanın tamamını arar (tüm yol bulma aracılarına ulaştıktan sonra erken çıkabilirsiniz). Ancak daha fazla düşman ekledikçe, paylaşılan yol parçalarını defalarca hesaplamak yerine giderek daha fazla yol bulma maliyetini paylaşırlar. Ayrıca, BFS / Dijkdtra'ların A * 'dan daha basit ve incelenen hücre başına değerlendirmek için genellikle daha ucuz olmasından bir avantaj elde edersiniz.

Kesinti noktası tam olarak tek tek A * 'dan daha ucuz olan A *' ya, daha ucuz olan notlama (geçmiş yol bulma sorgusu için bazı sonuçları yeniden kullandığınız yerde), akan alanlara daha ucuz, uygulamanıza, aracıların sayısına ve haritanızın boyutuna bağlı olacaktır. Ancak, sınırlı bir alanda birden çok yönden yaklaşan büyük bir düşman sürüsü planlıyorsanız, bir akış alanı neredeyse kesinlikle yinelenen A * 'dan daha ucuz olacaktır.

Aşırı bir örnek olarak, burada makul bir şekilde küçük bir ızgarada eş zamanlı olarak yol bulma yapan 20.000 aracıyla bir video görebilirsiniz .


Bu teknik kulağa hoş geliyor. Onu ben kontrol edecegim.
Darin Beaudreau

15
Haritanın A * 'ya tekrarlanan çağrılarından daha fazla arama yapmadan ve asla aynı pozisyonu iki kez aramadan kısmi bir akış alanı oluşturan hibrit bir algoritma kullanmak mümkündür . Temel fikir, rastgele bir düşman seçmek ve oyuncudan o düşmana doğru bir A * araması başlatmak ve hücreleri normal akış alanı üretiminde olduğu gibi karşılaştığınız şekilde işaretlemektir. Arama bu düşmanı bulduğunda , hedef olarak başka bir düşman seçin (henüz bulamadınız), açık seti yeni sezgisel göre yeniden sıralayın ve aramaya devam edin. Tüm düşmanları bulduğunda dur.
Ilmari Karonen

1
Çarpışmalardan kaçınmaya ne dersiniz? Bu (biraz) OP'de bahsediliyor (oyuncuya ulaştıklarında kırpılmayı önlüyor). Bana her şey taşındığında (veya bazı ek mantık eklemek) tam djikstras yeniden çalıştırmak zorunda görünüyor
Mars

2
@Mars OP akın hakkında konuşuyor, bu yüzden tüm bireylerin aynı hızda hareket edebileceğini varsayıyorum; çarpışmaların sorun olacağı tek yerler, sürünün bir kısmının durmasını ve beklemesini gerektiren darboğazlardır. Bununla birlikte, yol bulmayı gerçekten değiştirmek gerekmez - basit bir kuyruk muhtemelen çoğu durumda yeterince iyi çalışır ve bazı yollara ağırlık verme (benzer maliyetlere sahip alternatif yolların bazı sahte rastgele seçimleri) daha doğal görünümlü sürüler üretmek için çalışır aynı zamanda tek bir karo boşluğu geçmeye çalışırken tüm sürüyü önlemek akışları :)
Luaan

3
@Luaan Karo tabanlı bir oyunda çarpışmaların ne sıklıkta gerçekleştiğine şaşıracaksınız. Şahsen, "kuyruk" seçeneğini optimalden daha az buluyorum. Ayrıca, birimler birbirinden geçemezse, birimler son konumlarına ve bir dizi diğer kenar durumuna girmeye başladığında yeniden hesaplamanız gerekir. Akın zor;)
Mars

8

A * performansı ağır değildir. Bu duruma algoritmaları değiştirerek yaklaşırdım. Zaman zaman ve aralarında A * yapın, bir sonraki adımın adım atmakta serbest olup olmadığını veya kaçınmaya ihtiyacınız olup olmadığını kontrol edin.

Örneğin, bir eşiğin üzerindeyse oyuncuların A * hedef konumundan uzaklığını takip edin a * 'yı yeniden hesaplayın ve ardından güncelleme hareketlerini yapın. Çoğu oyun yol noktalarının bir kombinasyonunu kullanır, örneğin yol bulma için basitleştirilmiş bir ızgara ve geçiş noktaları arasındaki kaçınma yönlendirme algoritmaları ile geçiş noktaları arasındaki hareketi idare eden bir mantık. Temsilciler, yakınlarındaki engeller etrafında manevra yaparak uzak bir ara noktaya koşmaya çalışıyorlar bence en iyi yaklaşım.

Burada sonlu durum makineleri ile çalışmak ve Mat Buckland'ın "Örnek AI'yı Programlama" kitabını okumak en iyisidir. Kitap, probleminiz için kanıtlanmış teknikler sunar ve gerekli matematiği detaylandırır. Kitaptaki kaynak kodu web'de mevcuttur; kitap C ++ dilinde ancak bazı çeviriler (Java dahil) mevcuttur.


2
Nadiren güncellenen bir A * yaklaşımıyla, güncellemelerinizi kademelendirerek, kaç düşmanın tek bir karede yeniden yol vermesine izin verildiğine dair bir bütçe sağlayarak faydalı olabilir. Bu şekilde, kare başına en yüksek yol bulma maliyetinizi sınırlandırabilir ve toplam maliyetlerini birkaç kare üzerinden amorti ederek birçok AI yolunu daha güçlü bir şekilde ele alabilirsiniz. Çerçeve bütçesi aşıldığında bir veya iki kare için eski bir yol kullanan bir AI veya yakınsa ölü hesaplamaya geri dönme genellikle rahatsız edici olmaz.
DMGregory

2
Muhtemelen burada bariz olanı belirtmekle birlikte, belirli bir karedeki yollarınızın yalnızca bir kısmını güncelleyecekseniz , oynatıcıya olan mesafeye dayalı bir öncelik sistemi isteyebilirsiniz. Oyuncunun yakınındaki düşmanların yollarını güncellemesi daha önemliyken, uzaktaki düşmanların eski bir yol kullanması büyük olasılıktır.
AC

4

Sadece mümkün değil, 90'larda ticari bir oyunda yapıldığına inanıyorum - BattleZone (1998).

Bu oyunda ücretsiz karo temelli olmayan hareket ve 3B temelli karo temelli birimler vardı.

İşte böyle görünüyordu:

Birincisi, A * veya benzeri bir şey (muhtemelen bir yolun ne kadar süre bulabileceğine dair kesin sınırlarla A *'nın bir varyasyonu, bu yüzden çalıştırmak için asla çok fazla kaynak gerektirmez, ancak her zaman hedefe kadar bir yol bulamaz) bir hovertankın karo tabanlı engellere takılmadan hedefine ulaşması için bir yol bulmak için kullanılır.

Daha sonra tank, yolundaki yakındaki bir karonun ortasına çekildi ve engeller, yakındaki diğer tanklar vb.Ile püskürtüldü.


1
Peki, yolu takip etmenin iyi bir yolu nedir, ama tam olarak değil? Eğer küçük virajlara izin verirsem, düşmanın bir engelin köşesiyle çarpışmasını durdurabilmem gerekir. Akın davranışını hem düşmanlar hem de engeller için tutmalı ve bu durumlarla başa çıkmak için A * eklemeli miyim?
Darin Beaudreau
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.