Amacım modüler / olabildiğince genel bir öğe sistemi oluşturmaktır.
- Yükseltilebilir Öğeler (+6 Katana)
- Stat Değiştiricileri (+15 el becerisi)
- Öğe Değiştiriciler (% X Y hasar verme şansı, donma şansı)
- Şarj Edilebilir Öğeler (30 kullanımlık sihirli personel)
- Ögeleri Ayarla (Y özelliğini etkinleştirmek için 4 adet X seti ayarlayın)
- Nadirlik (ortak, benzersiz, efsanevi)
- Dezenfekte edilebilir (bazı işçilik malzemelerine ayrılır)
- Hazırlanabilir (belirli malzemelerle üretilebilir)
- Sarf malzemesi (5 dakika% X saldırı gücü, iyileşme +15 hp)
* Aşağıdaki kurulumda kalın özellikleri çözebildim.
Şimdi aklımdakileri yansıtmamız için bize birçok seçenek eklemeye çalıştım. Tüm bu özellikleri gerekli şekilde eklemeyi planlamıyorum, ancak uygun gördüğüm şekilde bunları uygulamak istiyorum. Bunlar ayrıca envanter sistemi ve verilerin serileştirilmesi ile de uyumlu olmalıdır.
Kalıtım kullanmayı hiç değil de varlık bileşeni / veri odaklı bir yaklaşım kullanmayı planlıyorum . Başlangıçta aşağıdakileri içeren bir sistem düşündüm:
- BaseStat: hareket halindeyken istatistikleri tutan genel bir sınıf (öğeler ve karakter istatistikleri için de kullanılabilir)
- Öğe: listesi, adı, öğe türü ve kullanıcı arabirimi, actionName, açıklama vb. İle ilgili verileri içeren bir sınıf.
- IWeapon: silah arayüzü. Her silahın IWeapon'ın uygulandığı kendi sınıfı olacak. Bu saldırı ve karakter istatistiklerine bir referans olacaktır. Silah donatıldığında, verileri (Item sınıfı 'stat) karakter statüsüne enjekte edilecektir (BaseStat ne olursa olsun, karakter sınıfına Stat bonusu olarak eklenecektir) Yani, örneğin, bir kılıç ( json ile eşya sınıfları üretir) bu yüzden kılıç karakter istatistiklerine 5 saldırı ekler . Yani ("Saldırı", 5) olarak bir BaseStat'ımız var ( enum'u da kullanabiliriz). Bu istatistik, donatıldıktan sonra karakterin "Saldırı" statüsüne BonusStat (farklı bir sınıf olacaktır) olarak eklenecektir. Böylece adlı bir sınıf Sword uygular IWeapon oluşturulacaktır zaman'Öğe Sınıfı yaratılır. Bu yüzden karakter istatistikleri enjekte edebiliriz ve Saldırı yöntemine hasar verebilir.Bu kılıcın içine ve saldırırken, karakter statüsünden toplam Saldırı statüsünü alabilir
- BonusStat: BaseStat'a dokunmadan istatistikleri bonus olarak eklemenin bir yoludur.
- IConsumable: IWeapon ile aynı mantık. Doğrudan stat eklemek oldukça kolaydır (+15 hp) ancak bu kurulumla geçici silahlar eklemekten emin değilim (5 dakika boyunca saldırmak için% x).
- IUpgradeable: Bu kurulum ile uygulanabilir. UpgradeLevel'i silah yükselttikten sonra artan bir temel stat olarak düşünüyorum . Yükseltildiğinde, yükseltme düzeyine uyacak şekilde weapon'un BaseStat'ını yeniden hesaplayabiliriz .
Bu noktaya kadar sistemin oldukça iyi olduğunu görebiliyorum. Ancak diğer özellikler için başka bir şeye ihtiyacımız olduğunu düşünüyorum, çünkü örneğin CASEtable özelliğini BaseStat'ım olarak uygulayamıyorum . Tüm malzemeleri Stat olarak ekleyebilirim ama bu mantıklı değil.
Buna katkıda bulunmanızı kolaylaştırmak için, size yardımcı olabileceğiniz bazı sorular:
- Diğer özellikleri uygulamak için bu kuruluma devam etmeli miyim? Kalıtım olmadan mümkün olabilir mi?
- Tüm bu özellikleri miras olmadan uygulamak için aklınıza gelebilecek herhangi bir yol var mı?
- Öğe Değiştiriciler hakkında, bunu nasıl başarabiliriz? Çünkü doğasında çok geneldir.
- Bu tür bir mimariyi inşa etme sürecini kolaylaştırmak için ne yapılabilir, herhangi bir tavsiye?
- Bu problemle ilgili olarak kazabileceğim herhangi bir kaynak var mı?
- Gerçekten mirastan kaçınmaya çalışıyorum, ancak bunların oldukça sürdürülebilir olmasını sağlarken mirasla kolaylıkla çözüleceğini / başarılacağını düşünüyor musunuz?
Soruları çok geniş tuttuğumdan, farklı yönlerden / insanlardan bilgi alabilmem için tek bir soruyu cevaplamaktan çekinmeyin.
DÜZENLE
@ Jjimenezg93 yanıtını takiben, test için C # 'da çok temel bir sistem oluşturdum, işe yarıyor! Bir şey ekleyip ekleyemeyeceğinize bakın:
public interface IItem
{
List<IAttribute> Components { get; set; }
void ReceiveMessage<T>(T message);
}
public interface IAttribute
{
IItem source { get; set; }
void ReceiveMessage<T>(T message);
}
Şimdiye kadar, IItem ve IAttribute temel arayüzlerdir. Mesaj için temel bir arayüz / özniteliğe (düşünebileceğim) gerek yoktu, bu yüzden doğrudan bir test mesajı sınıfı yaratacağız. Şimdi test sınıfları için:
public class TestItem : IItem
{
private List<IAttribute> _components = new List<IAttribute>();
public List<IAttribute> Components
{
get
{
return _components;
}
set
{
_components = value;
}
}
public void ReceiveMessage<T>(T message)
{
foreach (IAttribute attribute in Components)
{
attribute.ReceiveMessage(message);
}
}
}
public class TestAttribute : IAttribute
{
string _infoRequiredFromMessage;
public TestAttribute(IItem source)
{
_source = source;
}
private IItem _source;
public IItem source
{
get
{
return _source;
}
set
{
_source = value;
}
}
public void ReceiveMessage<T>(T message)
{
TestMessage convertedMessage = message as TestMessage;
if (convertedMessage != null)
{
convertedMessage.Execute();
_infoRequiredFromMessage = convertedMessage._particularInformationThatNeedsToBePassed;
Debug.Log("Message passed : " + _infoRequiredFromMessage);
}
}
}
public class TestMessage
{
private string _messageString;
private int _messageInt;
public string _particularInformationThatNeedsToBePassed;
public TestMessage(string messageString, int messageInt, string particularInformationThatNeedsToBePassed)
{
_messageString = messageString;
_messageInt = messageInt;
_particularInformationThatNeedsToBePassed = particularInformationThatNeedsToBePassed;
}
//messages should not have methods, so this is here for fun and testing.
public void Execute()
{
Debug.Log("Desired Execution Method: \nThis is test message : " + _messageString + "\nThis is test int : " + _messageInt);
}
}
Bunlar gerekli kurulumlardır. Şimdi sistemi kullanabiliriz (Aşağıdaki Unity içindir).
public class TestManager : MonoBehaviour
{
// Use this for initialization
void Start()
{
TestItem testItem = new TestItem();
TestAttribute testAttribute = new TestAttribute(testItem);
testItem.Components.Add(testAttribute);
TestMessage testMessage = new TestMessage("my test message", 1, "VERYIMPORTANTINFO");
testItem.ReceiveMessage(testMessage);
}
}
Bu TestManager komut dosyasını sahnedeki bir bileşene ekleyin ve hata ayıklamada iletinin başarıyla iletildiğini görebilirsiniz.
Bir şeyleri açıklamak için: Oyundaki her öğe IItem arabirimini uygulayacak ve her Öznitelik (ad sizi karıştırmamalı, öğe özelliği / sistemi anlamına gelir. Yükseltilebilir veya sökülebilir gibi) IAttribute uygulayacaktır. Sonra mesajı işlemek için bir yöntemimiz var (neden mesaja ihtiyacımız var daha fazla örnekte açıklanacaktır). Böylece bağlamda, bir öğeye nitelikler ekleyebilir ve gerisini sizin için yapmanıza izin verebilirsiniz. Bu çok esnektir, çünkü özellikleri kolayca ekleyebilir / kaldırabilirsiniz. Yani sözde bir örnek Disenchantable olur. Disenchantable (IAttribute) adında bir sınıfa sahip olacağız ve Disenchant yönteminde bunu isteyeceğiz:
- İçerikleri listeleyin (öğe devre dışı bırakıldığında, oyuncuya hangi öğe verilmelidir) not: Öğe, ItemType, ItemID vb.
- int resultsModifier (hayal kırıklığı özelliğini bir çeşit artırma uygularsanız, devre dışı bırakıldığında alınan bileşenleri artırmak için buraya bir int iletebilirsiniz)
- int başarısızlık Değişim (eğer fesat sürecinin başarısız olma şansı varsa)
vb.
Bu bilgiler DisenchantManager adlı bir sınıf tarafından sağlanacak, öğeyi alacak ve bu mesajı öğeye (devre dışı bırakıldığında öğenin bileşenleri) ve oyuncu ilerlemesine (sonuçModifier ve failChance) göre oluşturacaktır. Bu iletiyi iletmek için, bu ileti için bir gövde görevi görecek bir DisenchantMessage sınıfı oluşturacağız. Böylece DisenchantManager bir DisenchantMessage dolduracak ve öğeye gönderecektir. Öğe mesajı alır ve ekli tüm Özelliklerine iletir. Disenchantable sınıfının ReceiveMessage yöntemi bir DisenchantMessage arayacağından, bu mesajı yalnızca Disenchantable özniteliği alır ve üzerinde hareket eder. Umarım bu benim için yaptığı şeyleri temizler :).