Bir süredir 2d RPG üzerinde çalışıyorum ve bazı kötü tasarım kararları aldığımı fark ettim. Özellikle bana sorun yaratan birkaç şey var, bu yüzden diğer insanların bunları aşmak için ne tür tasarımlar kullandığını veya kullanacağını merak ediyordum.
Küçük bir arka plan için, geçen yaz boş zamanımda üzerinde çalışmaya başladım. Başlangıçta oyunu C # 'da yapıyordum, ama yaklaşık 3 ay önce C ++' a geçmeye karar verdim. C ++ üzerinde iyi bir ele sahip olmak istedim, çünkü yoğun bir şekilde kullandığımdan beri bir süredir oldu ve bunun gibi ilginç bir projenin iyi bir motivasyon kaynağı olacağını düşündüm. Destek kütüphanesini kapsamlı bir şekilde kullanıyorum ve grafikler için SFML ve ses için FMOD kullanıyorum.
Yazılı bir kod biraz var, ama kazıma ve baştan düşünüyorum.
İşte sahip olduğum ve diğerlerinin onları çözme veya çözme şekli hakkında bazı görüşler almak istediğim önemli endişe alanları.
1. Döngüsel Bağımlılıklar Oyunu C # 'da yaparken, bu konuda endişelenmem gerekmiyordu çünkü bu bir sorun değil. C ++ 'a geçersek, bu oldukça büyük bir sorun haline geldi ve işleri yanlış tasarladığımı düşündürdü. Sınıflarımı nasıl ayıracağımı ve hala istediğimi yapmasını gerçekten hayal bile edemiyorum. İşte bir bağımlılık zincirine birkaç örnek:
Bir durum etkisi sınıfım var. Sınıf, efektleri bir karaktere uygulamak için çeşitli yöntemlere (Uygula / Uygulamayı Kaldır, Kene vb.) Sahiptir. Örneğin,
virtual void TickCharacter(Character::BaseCharacter* character, Battles::BattleField *field, int ticks = 1);
Bu fonksiyon, durum efekti uygulayan karakter her dönüş yaptığında çağrılır. Regen, Poison, vs. gibi efektleri uygulamak için kullanılır. Ancak BaseCharacter sınıfına ve BattleField sınıfına bağımlılıklar da getirir. Doğal olarak, BaseCharacter sınıfının şu anda üzerlerinde hangi durum etkilerinin etkin olduğunu takip etmesi gerekir, bu da döngüsel bir bağımlılıktır. Battlefield'ın savaşan tarafları takip etmesi gerekiyor ve parti sınıfında başka bir döngüsel bağımlılık getiren BaseCharacters listesi var.
2 - Etkinlikler
C # 'da karakterleri, savaş alanlarını vb. .) ve savaş alanı / grafik bileşenleri etkilerini güçlendirmek için bu delegelere bağlanırdı. C ++ 'da benzer bir şey yaptım. Açıkçası C # delegelerine doğrudan eşdeğer yok, bu yüzden bunun gibi bir şey yarattım:
typedef boost::function<void(BaseCharacter*, int oldvalue, int newvalue)> StatChangeFunction;
ve karakter sınıfımda
std::map<std::string, StatChangeFunction> StatChangeEventHandlers;
ne zaman karakterin stat değişti, ben yineleme ve harita üzerinde her StatChangeFunction çağırır. Çalışırken, bir şeyler yapmak için kötü bir yaklaşım olduğundan endişeliyim.
3 - Grafikler
Bu büyük bir şey. Kullandığım grafik kütüphanesi ile ilgili değil, daha çok kavramsal bir şey. C #, ben korkunç bir fikir olduğunu biliyorum benim sınıf bir sürü ile grafik birleştiğinde. Bunu yapmak istedim bu sefer farklı bir yaklaşım denedim.
Grafiklerimi uygulamak için, oyunla ilgili her şeyi bir dizi ekran olarak hayal ediyordum. Bir başlık ekranı, bir karakter durumu ekranı, bir harita ekranı, bir envanter ekranı, bir savaş ekranı, bir savaş GUI ekranı var ve temel olarak oyun grafiklerini oluşturmak için gerektiğinde bu ekranları üst üste koyabilirim. Etkin ekran ne olursa olsun, oyun girişine sahiptir.
Kullanıcı girişine göre ekranları iten ve pop yapan bir ekran yöneticisi tasarladım.
Örneğin, bir harita ekranındaysanız (Döşeme Haritası için bir giriş işleyici / görselleştirici) ve başlat düğmesine basarsanız, bir Ana Menü ekranını harita ekranının üzerine itmek ve haritayı işaretlemek için ekran yöneticisine bir çağrı yapılması gerekir. ekran çizilemez / güncellenmez. Oynatıcı menüde gezinir ve ekran yöneticisine yeni ekranları ekran yığınına itmek için ekran yöneticisine daha fazla komut verir, ardından kullanıcı ekranları değiştirdiğinde / iptal ettiğinde onları açar. Sonunda oyuncu ana menüden çıktığında, onu açıp harita ekranına geri döneceğim, çizileceğini / güncellendiğini ve oradan gitmesini söyledim.
Savaş ekranları daha karmaşık olurdu. Arka plan olarak hareket edecek bir ekranım, savaştaki her bir tarafı görselleştirmek için bir ekranım ve savaş için kullanıcı arayüzünü görselleştirmek için bir ekranım olacaktı. Kullanıcı arabirimi karakter olaylarına bağlanır ve bunları kullanıcı arabirimi bileşenlerinin ne zaman güncelleneceğini / yeniden çizileceğini belirlemek için kullanır. Son olarak, kullanılabilir bir animasyon komut dosyasına sahip her saldırı, ekran yığınından çıkmadan önce kendini canlandırmak için ek bir katman çağırır. Bu durumda, her katman sürekli olarak çekilebilir ve güncellenebilir olarak işaretlenir ve savaş grafiklerimi işleyen bir ekran yığını alıyorum.
Ekran yöneticisinin henüz mükemmel çalışmasını sağlayamasam da, biraz zaman ayırabileceğimi düşünüyorum. Bununla ilgili sorum şu: Bu hiç de faydalı bir yaklaşım mı? Kötü bir tasarımsa, ihtiyacım olacak tüm ekranları yapmak için çok fazla zaman harcamadan önce şimdi bilmek istiyorum. Oyununuz için grafikleri nasıl oluşturuyorsunuz?