Farklı türdeki varlıkların listelerini yönetmek - daha iyi bir yol var mı?


9

Mobil cihazlar için 2D bir uzay oyunu geliştiriyorum, ancak gerçekten karmaşıklaşıyor ve çözümüm gerçekten kafa karıştırıcı ve çok sayıda tekrarlanan kod segmenti üretiyor.

Ben hava gibi farklı nesnenin multible listeleri var bir dünya sınıfı:

List<Enemy> enemys;
List<Projectile> projectiles;
List<Collectable> collectables;
List<Asteroid> asteroids;
List<Effect> effects;
..

Her liste dünya sınıfı tarafından güncellenir. ama hepsi bu değil .. Her düşmanın bir motor listesi ve düşman tarafından güncellenen silah listesi var. Artık her motor, dünya listesindeki 'efektlere' bazı yangın efektleri ekliyor ve her silahlı silah, dünya listesindeki 'mermilere' mermi ekliyor. Tüm bu sınıflar farklı parametre var, bu yüzden her sınıf için ekstra bir güncelleme VE ekstra render işlevi gerekir.

En azından hepsi, konum, hız ve ivme vektörleri, sınırlayıcı çokgenler ve ApplyForce ve sonlu durum makinesi gibi işlevler gibi temel şeyleri sağlayan 'GameObject' in çocuklarıdır.

Bunu yapmanın daha iyi veya daha yaygın bir yolu var mı? tüm farklı nesneler için olası tüm parametreleri ve yöntemleri içeren bir tümünü yakala sınıfı gibi. (bu daha da kafa karıştırıcı kod üreteceğini düşünüyorum)


Bu soruma benzer: gamedev.stackexchange.com/questions/22559/… Verilen cevaplara bakmanızı öneririm.
Derek

Yanıtlar:


5

Bunu yapmanın daha iyi veya daha yaygın bir yolu var mı? tüm farklı nesneler için olası tüm parametreleri ve yöntemleri içeren bir tümünü yakala sınıfı gibi.

Evet, buna mimari. Ayrıntılar için buraya bir göz atın .

Bu, dünya sınıfınızdaki varlıkların yalnızca bir listesine izin verir:

List<Entity>

Kompozisyonun miras üzerine bir örneğidir .


3

Orijinal sorunuzun sınırları dahilinde seçeneklerden biri, listeleriniz gibi Türler yerine İşlemler'e bölünmesi olacaktır. Örneğin, olurdu List<HasAI>ve için tek List<Collidable>ve yeni bir nesne oluşturmak zaman nesne daha sonra imha edildiğinde ihtiyacı neyse eylem listesi, bu o listelerden kendisini kaldırır kendisini ekler. Bir nesne birden fazla listede olabilir.

Bu seçeneğin ikinci adımı, sınıflarınızı bir hiyerarşiden Arabirimler kullanan bir tanesine yeniden düzenlemektir, bu nedenle HasAI türünüz örnek olarak IBrains arabirimini uygulayan bir sınıftır. Bu Eşleştirme List<HasAI>sadece nesneleri gerektirir IBrains arayüze sahip.

Bu, bazı karmaşıklığın temizlenmesine yardımcı olmalıdır.


2

Yapmanız gereken şey, kendi sınıflarına renderleme yapmak olduğunu düşünüyorum, sanırım bir oyuncu ve diğeri düşman için (veya belki de oyuncu için sadece bir tane ve sonra oyuncu ve düşman için bunun bir örneğini yaratın -% 100 emin değilim) oyun tasarımı.)

Oluşturucunun çeşitli nesnelerin etrafında dönmesine izin vermek ve ne çizeceğine karar vermek için bir ziyaretçi deseni kullanabilirsiniz, bu daha az karmaşık olabilir.


2

Bir temel sınıf kullanmak ve polimorfizme güvenmek çok iyi bir fikirdir. Ancak bazı alternatif yaklaşımlar var. Noel Llopis tarafından okunmaya değer iki makale var. Son zamanlarda Veri Odaklı Tasarım'a bakıyorum ve bunun bir değeri olduğunu düşünüyorum.

Makaleler burada ve burada . Kodunuzu polimorfizmden biraz daha basitleştirebilir. Ama YMMV gibi, bir göz atın ve elde etmeye çalıştığınız şeye uyup uymadığına bakın. Polimorfizm kalıtım kullanır ve DOD, hem artıları hem de eksileri olan toplama kullanır, bu nedenle zehirinizi seçin.


1

OOP ve özellikle polimorfizm kullanarak yapabilirsiniz.

Temel olarak, tüm oyun varlıklarının miras aldığı bir temel sınıf oluşturmanız gerekir. Bu temel sınıf, olabildiğince soyut, bir Oluşturma, Güncelleme ve Belki de Yok Etme işlevi gibi şeyler içerecektir.

Sonra diğer tüm oyun nesnelerinizi bu sınıftan alırsınız. Diliniz desteklemiyorsa, daha gelişmiş şeyler yapmak için muhtemelen kodunuza bir tür yansıma eklemeniz gerekecektir, ancak mirasınızı doğru bir şekilde nasıl yapılandıracağınızı biliyorsanız önlenebilir.


1
Bunu zaten yaptı - tüm sınıfları GameObject'in çocukları. Sadece bir dizi listeyi tek bir GameObjects listesine dönüştürmesi gerekiyor.
SomeGuy
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.