Sıra tabanlı, mesafe tabanlı strateji oyununda olası hareket aralığı nasıl belirlenir?


11

C ++ ve SFML-2.0 kullanarak 2 boyutlu, sıra tabanlı bir strateji oyunu oluşturuyorum. Hareket, ızgara tabanlı olmaktan ziyade mesafeye dayalıdır ve belirli bir dönüşte her biri yerinde dönebilen veya ileri doğru hareket edebilen birkaç farklı üçgen şekilli parça ile.

Hareket, oyuncu parçanın taşınacağı bir yer seçecek ve parçanın alması için potansiyel bir yol oluşturacak şekilde çalışacaktır. Oyuncu kararını onayladıktan sonra, taş bu yol boyunca istenen yere hareket edecektir. Yollar iki faktörle sınırlıdır: mesafe, bir parçanın ne kadar uzağa gidebileceğini, herhangi bir dönüşü hesaba katarak (böylece bir eğri varsa, doğrudan noktadan noktaya değil, eğri boyunca uzunluk olacaktır); ve direksiyon açısı, hareket halindeyken (örneğin, -30 ila 30 derece) herhangi bir noktada (ve her bir noktaya kadar) dönebilir.

Benim sorum, oyuncunun parçanın taşınması için seçebileceği potansiyel yerlerin aralığını nasıl belirleyeceğim?

Burada hangi denklemlerin ve / veya algoritmanın kullanılacağından tam olarak emin değilim. Orijinal planım aşırı derecede karmaşıktı, açıklamak yerine, uygulamanın imkansız olduğu noktaya kadar, ve bu noktada durduğum proje ile tamamen kayboldum.

Bir birimin dönüş yarıçapını dikkate alarak hareket edebileceği aralığı nasıl belirleyebilirim?

Örneğin, aşağıdaki resimde. Kırmızı, mavi ve yeşil çizgilerin hepsi aynı uzunlukta olacaktır. Mor daire, ünitenin hareket edebileceği hareket aralığını gösterir. (Şekil muhtemelen yanlış ve çizgiler muhtemelen değildir aslında aynı uzunlukta, ancak fikir)

resim açıklamasını buraya girin


Hala aynı (toplam) mesafeyi hareket ettirebilecektir. Yani soru gerçekten "ne kadar dönüyor?" / "Ne kadar dönmesi gerekiyor?" / " Nereye dönmesi gerekiyor?" Muhtemelen normal yolu belirlemekten başlamanız gerekir, daha sonra belirli bir miktarın üzerindeki açılar için geri dönüş için bir adım geri adım atmanız gerekir; nihai mesafenin eğrilerden daha uzun bir düz çizgi yolunda (en son dönüş) olacağını unutmayın.
Clockwork-Muse

Evet, kat edilen mesafe ana sınırlayıcı faktördür. Buradaki en büyük engelim, parçanın dönebileceği ve dönmeye devam edebileceği herhangi bir noktada, hala kullanılabilir mesafe kaldığı sürece dikkate almam gerektiğidir.
sfphilli

Ne demek, bir birimin hareket edebileceği menzil? Yani taşınabileceği noktalar mı demek istiyorsun? Doğrusal cebire (vektörler) ne kadar aşinasınız?
BlueRaja - Danny Pflughoeft

1
Hangi gerçek hayat senaryosunu modellemeye çalışıyorsunuz? Sorununuz gereksinimler konusunda çok belirsiz ve çok fazla çözüm yaklaşımı öneriliyor. Bu alandaki her özel soruna (neredeyse) iyi bilinen bir yaklaşım vardır, ancak herkes bu birçok sorundan hangisini gerçekten ele aldığınızı tahmin etmektedir.
Pieter Geerkens

1
@PieterGeerkens Bence OP kod istemediği için bir algoritma istiyorlar. Ve bir algoritmanın makul bir şekilde tasarlanabileceği senaryosu hakkında yeterli ayrıntı sağladı. Bu yaygın ve kabul edilebilir.
MichaelHouse

Yanıtlar:


4

Dijsktra's kullanarak bir akış veya mesafe alanı oluşturun.

Esasen, hedef olmayan Dijkstra algoritmasını kullanarak bir tablo doldurun (muhtemelen bunun için farklı bir isim; bilmiyorum). Her bir açık düğümü alın, erişilebilir komşuları hesaplayın, açık listeye itin, kapalı listeye ayarlayın, üst düğümün "sonraki" yolunu uygun şekilde güncelleyin, vb.

Sonuç artık başlangıca nasıl geri döneceğinize dair tüm düğümlerinizin bir ağına sahip olmanız olacaktır. Ulaşılamayan düğümlere ilk adımda dokunulmaz. Ulaşılabilen düğümlerde "üst düğüme mümkün olan en iyi yol boyunca bir sonraki düğüm" öğesi hesaplanır, böylece hem tüm düğümleri vurgulayabilir, hem de kullanıcı vurgulanan alanları gezdirirken veya tıklarken hareket yolunu göstermek veya yürütmek için bu bilgileri kullanabilirsiniz.


Kavramı nasıl açıklayacağımı ya da nasıl uygulayacağımı değil, ama kesinlikle doğru yaklaşımı.
Pieter Geerkens

Algoritmayı anladığım gibi, düğüm geçişinin yoldan bağımsız olması gerektiği. Bu nedenle, bunu başarmak için, karşı karşıya kalmaya adanmış başka bir özgürlük derecesi (düğümlerinizi oluşturmak için başka bir eksen) eklemeniz gerekir. Başka bir deyişle, farklı X, Y, potansiyel olarak Z ve Facing'in her kombinasyonu için bir düğümünüz olurdu. Aksi takdirde, bir düğüme girmek için en kısa yolu bulmak, ayrılırken farklı yüzleri ayırt etmez. Bu doğru mu? Bu durumda, bu yöntem muhtemelen çok yoğun mu?
TASagent

@TASagent: iyi bir nokta, bunu tamamen düşünmedim. Algoritma belki biraz kapalı ama yaklaşım işe yarayacak.
Sean Middleditch

@PieterGeerkens: Kötü bir açıklama olduğuna katılıyorum. Her şeyi daha iyi açıklayan kendi cevabınızı yapmalısınız.
Sean Middleditch

Bu, ihtiyacım olana oldukça yakın görünüyor, ancak itiraf etmeliyim ki bu algoritmayı hiç duymadım ve bu yüzden ihtiyacım olana nasıl genelleştireceğimizi bilmiyorum. Herhangi bir iyi bilgi veya öğretici bir bağlantı var mı?
sfphilli

4

Bir kaba kuvvet çözümü:

  1. Ünite ortada olacak şekilde ünitenin etrafında bir köşe çemberi oluşturun. Çemberin yarıçapı maksimum hareket mesafesidir. Köşelerin yoğunluğu, nihai sonucun ne kadar ayrıntılı olmasını istediğinize bağlı olarak değişebilir.
  2. Her tepe konumu için, ünite direksiyonunun bu konuma doğru hareketini simüle edin. Bu, render olmadan sıkı bir döngüde yapılır.
  3. Direksiyon simülasyonunda maksimum mesafeye ulaşıldığında, tepe noktasını simüle edilen birimin noktasına taşıyın. Bu nokta, mevcut dönüş sona ermeden önce ünitenin o tepe noktasına ulaşabileceği en yakın noktadır. Bunun, daireyi gerçek hareketin boyutuna küçültme etkisi vardır.
  4. Olası köşeleri, olası hareket mesafelerini çizmek üzere işlenmiş bir daire oluşturmak için birim üzerinde ortalanmış bir tepe noktasıyla birlikte kullanın.

resim açıklamasını buraya girin

Yani, mavi daireden başlayarak, mor daireyle sonuçlanan yollarınızı işlersiniz. Ardından, şekli görüntülemek için gereken kırmızı üçgenleri yapmak için bu noktaları birim üzerinde bir orta nokta ile kullanabilirsiniz. (Sadece bu görüntüyü yapmak o şeklin doğru olmadığını anlamamı sağlıyor, ama gerçekte neyin doğru olduğunu görmek ilginç olacak)


3

Başlangıçta önerdiğimden farklı bir yaklaşımı temsil ettiği için Sean'ın çözümünü ayrı bir cevapta genişleteceğim.

Bu çözüm muhtemelen en erişilebilir yöntemi temsil etmektedir. Ortamınızı düğümlere ayırmanızı gerektirir. Evet, bu ızgara tabanlı bir yaklaşımı yeniden ortaya koymaktadır, ancak nispeten ince yapılabilir veya düğüm içinde ele alınan daha ince konumlandırma ile geniş yol bulma için kullanılabilir. Düğüm yapısı ne kadar kaba olursa, yol bulma o kadar hızlı olur.

Buradaki büyük sorun, aslında gemiyle yüzleşmeyle uğraşmanızdır, bu nedenle birçok geleneksel yol bulma çözümü değişiklik yapılmadan kullanılamaz. Bunlar genellikle yoldan bağımsızdır, çünkü bulunduğunuz düğüme nasıl ulaştığınızı umursamazlar. Hızlanma, yavaşlama ve dönüş anında ve ücretsiz olduğunda iyi çalışır. Ne yazık ki sizin için dönüm ücretsiz değildir. Bununla birlikte, bu basitleştirmede bırakılan gerçekten fazladan bir bilgi parçası olduğundan, onu başka bir değişken olarak kodlayabiliriz. Fizikte bu, faz-uzay olarak bilinir.

Şimdilik 2 boyut varsayarsak, 3 boyut için tahmin yapabilirsiniz:

Normalde, izin verilen her ayrık koordinat konumu için bir düğüme ihtiyacınız olacaktır. Örneğin:

(0,0) - (1,0) - (2,0)
  | \  /  |  \  / |
(0,1) - (1,1) - (2,1)

Vb Bitişik noktaların bir düğümünü oluşturur ve bunları uzaysal bitişiklikle bağlarsınız. Sonra keşfedilen düğümlere bağlı keşfedilmemiş, canlı düğümler kalmayana kadar Dijkstra'nın algoritmasını, dönüş için izin verilen hareket değerini aşan düğümleri öldürürdünüz. Her düğüm ulaşmak için gereken en küçük mesafeyi takip eder.

Bu yöntemi Döndürme ile kullanılabilir olacak şekilde genişletmek için, aynı düğümün 3 boyutta olduğunu hayal edin. Z-yönü dönüşe / yüzeye karşılık gelir ve döngüseldir, yani + Z yönünde hareket etmeye devam ederseniz, başladığınız yere geri dönersiniz. Şimdi, bitişik konumlara karşılık gelen düğümler sadece bu yöne karşılık gelen kaplama boyunca bağlanır. Daha önce keşfedilmiş düğümlere bağlı düğümler üzerinde her zamanki gibi yineleme yaparsınız. Bu şemada N, NE, E, SE, S, SW, W, NW ile sınırlandırılmasını tavsiye ederim.

Bu çözüm size alanın tüm erişilebilir bölgelerinin yanı sıra oraya ulaşmanın en iyi yolunu, oraya vardığınızda ne kadar rotasyonunuz olduğunu ve oraya vardığınızda sahip olabileceğiniz yönlerin tümünü söyleyebilir.

Ardından, yolu gerçekten yürütürken, enterpolasyon yapmak / kübik spline'ı daha özgün görünmesini sağlamak için serbestsiniz.


1
Bu mükemmel. Algoritma üzerinde biraz araştırma yapmam ve oyunumda denemem gerekecek, ancak bu özellikle bana oyunun diğer bazı önemli kısımlarına genelleştirebildiğim için mükemmel uyum sağlıyor.
sfphilli

1

İlk önce hareket halindeyken dönüşü tam olarak nasıl istediğinize karar vermeniz gerekebilir. Gibi seçenekler:

  • Koni içinde hareket ederse, önce döndürün, sonra hareket etmeye başlayın. Bu, uygulanması ve yolu için daha kolay bir çözümdür. Ayrıca daha az ilginç, bu yüzden kullanmak istemem.

  • Toplam 45 dereceye kadar hareket ederken sürekli tornalama. Bu çok daha hileli ve umarım peşindesiniz. Sabit bir zaman çizelgesi kullanarak yolun sayısal olarak entegre edilmesi, muhtemelen buna yaklaşmanın en kolay yoludur. Koniniz maksimum (her adımda + X derece) ve minimum (her adımda -X derece) dönüşlerle sınırlanacaktır.

Bu gereksinimlerin ikincisi ile uzayda nasıl en iyi yol alınacağı büyük ölçüde hareket edecekleri ortama bağlıdır. Eğer etrafta dolaşmanız gereken birçok engel varsa, işler gerçekten zor ve gerçekten pahalı olabilir. Ancak, yoksa, istenen konuma ulaşmak için dönüşü önden yükleyebilir (ve hatta inceltebilirsiniz).

Sorunuz olan konuları yalnızca kısmen ele almış olabileceğimi hissediyorum, bu yüzden yorumlara daha fazla eklemekten çekinmeyin ve tartışmayı genişletebilirim.


Kesinlikle herhangi bir yol boyunca (örneğin) 45 dereceye ve potansiyel olarak her bir noktaya kadar dönme ikinci seçeneğini kullanmak istiyorum. Ayrıca her biri parçalardan daha büyük engeller olacaktır (dev kayaları düşünün). Başlangıçta bunu düşündüğüm yol, olası uç noktaların bir konisini oluşturmaktı ve daha sonra bu uç noktaların her biri için yeni bir koni üretti ve gidilen maksimum mesafeye ulaşana kadar mümkün olan her yer için. Bununla birlikte, bunu deli aşırı komplikasyonsuz nasıl uygulayacağımdan tam olarak emin değilim.
sfphilli

Hmmm, bazı detaylar hakkında biraz net değilim. Geriye bakınca, 'sıra tabanlı' belirlediğinizi ve birimlerin kendi sıralarında 'dönebileceğini ya da hareket edebileceğini' gördüğüm soruya bakıyorum. Bu, oyuncunun eylemlerini birçok tur önceden çizdiği ve hareket ederken yol bulmayı yapmak istediğiniz anlamına mı geliyor? Hareketin nasıl çalışması gerektiğine dair daha fazla açıklama yararlı olacaktır.
TASagent

Hayır, demek istediğim, belirli bir turda oyuncunun parçalarını istedikleri kadar yerinde döndürebilmeleri ya da zaten baktıkları yönde hareket edebilmeleriydi. Hareket ederlerse, bir yol boyunca belirli bir mesafeye gidebilirler ve hareket ederken belirli bir açıya (örneğin -45 ila 45 derece arasında herhangi bir yere) dönebilir veya yönlendirebilirler. Seçilen bir yolun sola veya sağa hareket etmek için bir eğri içereceğini düşünün. Yol, oyuncunun hareket etmek istedikleri bir noktayı seçerek belirleyebileceğim olası noktalar dahilinde belirlenir.
sfphilli

Tamam, aslında, maalesef, istediğiniz özelliklerin yukarıda bahsettiğimiz Dijkstra algoritması için çok kısıtlayıcı olduğu anlaşılıyor: - \. Muhtemelen. Daha sonra eve geldiğimde bunun için bazı şeyler çizeceğim.
TASagent

Sorunu orijinal soruya açıklığa kavuşturmak için topladığınız bu bilgilerin bir kısmını düzenlemek isteyebilirsiniz, böylece daha sonra gelen insanlar daha fazla bilgi ile başlayabilir.
TASagent
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.