Bunu hala okuyor musunuz emin değilim ama bu tür problemlerle uzun süredir mücadele ediyorum.
Çok sayıda farklı etki sistemi tasarladım. Şimdi kısaca onların üzerinden geçeceğim. Bunların hepsi benim tecrübeme dayanıyor. Tüm cevapları bildiğini iddia etmiyorum.
Statik Değiştiriciler
Bu tür sistemler çoğunlukla, herhangi bir değişikliği belirlemek için basit tam sayılara dayanır. Örneğin, +100'den Max HP'ye, +10'a saldırmak vb. Bu sistem aynı zamanda yüzdeleri de kaldırabilir. Sadece istifin kontrolden çıkmadığından emin olmanız gerekir.
Bu tür bir sistem için üretilen değerleri hiçbir zaman önbelleğe almadım. Örneğin, bir şeyin maksimum sağlığını göstermek isteseydim, o noktada değeri üretirdim. Bu, işlerin hataya yatkın olmasını engelledi ve katılan herkes için anlaşılması daha kolay.
(Java'da çalışıyorum, bu yüzden aşağıdakiler Java tabanlı ancak diğer diller için bazı değişikliklerle çalışmalı.) Bu sistem, değişiklik türleri için enums'ler ve ardından tamsayılar kullanılarak kolayca yapılabilir. Sonuçta, anahtar sıralı, değer sıralı çiftleri olan bir koleksiyona yerleştirilebilir. Bu hızlı arama ve hesaplamalar olacak, bu yüzden performans çok iyi.
Genel olarak, sadece düz statik statik değiştiriciler ile çok iyi çalışıyor. Yine de, kod değiştiricilerin kullanılması için uygun yerlerde kod bulunmalıdır: getAttack, getMaxHP, getMeleeDamage, vb.
Bu yöntemin başarısız olduğu yerde (benim için) bufflar arasında çok karmaşık bir etkileşim var. Biraz fazla getto yapmak dışında, etkileşime girmenin kolay ve kolay bir yolu yok. Bazı basit etkileşim olanaklarına sahiptir. Bunu yapmak için, statik değiştiricileri saklama biçiminizde bir değişiklik yapmalısınız. Anahtar olarak bir enum kullanmak yerine, bir String kullanırsınız. Bu Dize, Enum name + extra değişken olur. 10 üzerinden 9 kez, ekstra değişken kullanılmaz, bu yüzden enum adını anahtar olarak korursunuz.
Hızlıca bir örnek yapalım: Eğer ölümsüz yaratıklara karşı hasarı değiştirmek istiyorsanız, aşağıdaki şekilde sipariş edilmiş bir çifti olabilir: (DAMAGE_Undead, 10) DAMAGE Enum ve Undead ekstra değişkendir. Böylece, savaşınız sırasında, şöyle bir şey yapabilirsiniz:
dam += attacker.getMod(Mod.DAMAGE + npc.getRaceFamily()); //in this case the race family would be undead
Neyse, oldukça iyi çalışıyor ve hızlı. Ancak karmaşık etkileşimlerde başarısız oluyor ve her yerde “özel” kod kullanıyor. Örneğin, “ölüme ışınlanma% 25 şansı” durumunu düşünün. Bu “oldukça” karmaşık bir şey. Yukarıdaki sistem, aşağıdakilere ihtiyaç duyduğunuz gibi kolayca idare edebilir.
- Müzikçaların bu modda olup olmadığını belirleyin.
- Bir yerlerde, eğer başarılı olursa, ışınlanmayı yürütmek için bazı kodlar kullanın. Bu kodun yeri başlı başına bir tartışmadır!
- Mod haritasından doğru verileri alın. Değer ne anlama geliyor? Onlar da ışınlanacakları oda mı? Ya bir oyuncuda iki ışınlanma modu varsa? Tutarlar bir araya getirilmez mi ?????? HATASI!
Yani bu beni bir sonrakine getiriyor:
Üstün Karmaşık Buff Sistemi
Bir keresinde tek başıma bir 2D MMORPG yazmaya çalıştım. Bu çok büyük bir hataydı ama çok şey öğrendim!
Etki sistemini 3 defa yeniden yazdım. İlki, yukarıdakilerin daha az güçlü bir varyasyonunu kullandı. İkincisi hakkında konuşacağım şeydi.
Bu sistem her değişiklik için bir dizi sınıfa sahipti, bunlar şöyledir: ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent. Bir milyon insanım vardı - TeleportOnDeath gibi şeyler bile.
Sınıflarımda aşağıdakileri yapacak şeyler vardı:
- applyAffect
- removeAffect
- checkForInteraction <--- önemli
Uygula ve kaldır kendilerini açıkla (yüzdelik gibi şeyler için etki, etkinin ne zaman yıprandığından emin olmak için HP'nin ne kadar arttırdığını takip etse de, yalnızca eklediği miktarı kaldırır.) Buggy, lol ve doğru olduğundan emin olmak uzun zamanımı aldı. Hala iyi hissetmedim.).
CheckForInteraction yöntemi, karmaşık bir kod parçasıydı. Etkilerin (yani: ChangeHP) sınıflarının her birinde, bunun girdi etkisiyle değiştirilmesi gerekip gerekmediğini belirlemek için koda sahip olacaktır. Mesela, eğer bir şeye sahipseniz ...
- Buff 1: Saldırıya 10 Yangın hasarı verir
- Buff 2: Tüm yangın hasarlarını% 25 arttırır.
- Buff 3: Tüm yangın hasarlarını 15 arttırır.
CheckForInteraction yöntemi tüm bu etkilerin üstesinden gelirdi. Bunu yapmak için, yakındaki oyuncuların TÜMÜ üzerinde her bir etkinin kontrol edilmesi gerekiyordu! Bunun nedeni, bir alandaki birden fazla oyuncu ile yaptığım etkilerin türü. Bunun anlamı, ASLA HAD'ın yukarıdaki gibi herhangi bir özel ifadeyi HAD olarak tanımlamamasıdır - “sadece ölürsek, ölümle ilgili ışınlanma kontrolü yapmalıyız”. Bu sistem doğru zamanda otomatik olarak doğru şekilde işler.
Bu sistemi yazmaya çalışmak 2 ay kadar sürdü ve kafa tarafından yapılmış birkaç kez patladı. Ancak, gerçekten güçlüydü ve çok fazla miktarda şey yapabilirdi - özellikle oyunumdaki yetenekler için şu iki gerçeği göz önüne aldığın zaman: 1. Hedef aralıkları vardı (yani: tek, öz, sadece grup, PB AE özü) , PB AE hedefi, hedef AE, vb.) 2. Yetenekler üzerinde 1'den fazla etkiye sahip olabilir.
Yukarıda da bahsettiğim gibi, bu oyun için 3. etki sisteminden ikincisiydi. Neden bundan uzağa taşındım?
Bu sistem şimdiye kadar gördüğüm en kötü performansa sahipti! Devam eden her şeyi çok fazla kontrol etmek zorunda olduğu için çok yavaştı. İyileştirmeye çalıştım, ancak başarısız oldu.
Böylece üçüncü versiyonuma geldik (ve başka bir buff sistemi):
İşleyicileri ile Karmaşık Etki Sınıfı
Yani bu hemen hemen ilk ikisinin bir birleşimidir: Çok fazla işlevsellik ve ekstra veri içeren bir Affect sınıfında statik değişkenler olabilir. O zaman sadece işleyicileri çağırın (benim için, belirli eylemler için alt sınıflar yerine hemen hemen bazı statik yarar yöntemleri kullanın. Ancak bir şeyler yapmak istediğimizde eylemler için alt sınıflarla gidebileceğinizden eminim).
Affect sınıfı, hedef türleri, süre, kullanım sayısı, uygulama şansı vb. Gibi tüm sulu iyi öğelere sahip olacaktı.
Örneğin, ölümle ilgili ışınlanma gibi durumlarla başa çıkmak için özel kodlar eklememiz gerekir. Muharebe kodunda manuel olarak bunu kontrol etmemiz gerekirdi ve sonra da olsaydı, etkilerin bir listesini alırdık. Bu etki listesi, ölümle ilgili ışınlanma ile uğraşan oyuncudaki geçerli etkilerin tümünü içerir. Sonra her birine bakarız ve başarılı olup olmadığını kontrol ederdik (ilk başarılıda dururduk). Başarılıydı, bunun için sadece işleyiciyi arardık.
İsterseniz etkileşim yapılabilir. Sadece oyuncu / etc üzerinde meraklıları aramak için kodu yazmak zorunda kalacaktı. İyi bir performans gösterdiğinden (aşağıya bakınız), bunu yapmak için oldukça verimli olması gerekir. Sadece daha karmaşık işleyicilere vb. İhtiyaç duyacaktır.
Bu yüzden, ilk sistemin performansının büyük bir kısmı ve ikincisi gibi hala çok fazla karmaşıklığı vardır (fakat AS kadar değil). En azından Java'da, MOST vakalarında neredeyse birincisinin performansını elde etmek için bazı zor şeyler yapabilirsiniz (örneğin: enum haritasına sahip olmak ( http://docs.oracle.com/javase/6/docs/api/java) /util/EnumMap.html ) Enums tuşları ile ve ArrayList değerleri ile etkiler. Bu, hızlı bir şekilde etkilenip etkilenmediğini görmenizi sağlar [liste 0 olur veya harita enum olmazdı] ve sebepsiz yere oyuncunun etki listelerini sürekli yinelemek için: Şu anda onlara ihtiyacımız olursa etkilerini yinelemeyi umursamıyorum.
Şu anda 2005'te sona eren MUD'umu yeniden açıyorum (oyunu, orjinal haliyle olduğu FastROM kod tabanı yerine Java ile yeniden yazıyorum) ve yakın zamanda buff sistemimi nasıl uygulamak istiyorum? Bu sistemi kullanacağım çünkü önceki başarısız oyunumda iyi çalıştı.
Umarım, bir yerlerde birileri bu içgörülerin bir kaçını yararlı bulacaktır.