एक रोबस्ट आइटम सिस्टम बनाना


12

मेरा उद्देश्य संभव आइटम प्रणाली के रूप में एक मॉड्यूलर / जैसा कि सामान्य बनाना है जो चीजों को संभाल सकता है:

  • अपग्रेडेबल आइटम (+6 कटाना)
  • स्टेट मोडिफ़ायर (+15 निपुणता)
  • आइटम संशोधक (वाई नुकसान करने के लिए% X मौका, फ्रीज करने का मौका)
  • रिचार्जेबल आइटम (मैजिक स्टाफ 30 usages के साथ)
  • सेट आइटम (वाई सुविधा को सक्रिय करने के लिए एक्स सेट के 4 टुकड़े से लैस करें)
  • दुर्लभता (सामान्य, अद्वितीय, पौराणिक)
  • विनिर्मित (कुछ क्राफ्टिंग सामग्री में विघटित)
  • शिल्प करने योग्य (कुछ सामग्रियों के साथ तैयार किया जा सकता है)
  • उपभोज्य (5min% X हमला शक्ति, चंगा +15 hp)

* मैं उन सुविधाओं को हल करने में सक्षम था जो निम्नलिखित सेटअप में बोल्ड हैं।

अब मैंने कई विकल्पों को जोड़ने की कोशिश की, जो मेरे मन में हैं। मैं इन सभी आवश्यक सुविधाओं को जोड़ने की योजना नहीं बनाता, लेकिन जैसा कि मैं फिट देखता हूं, मैं उन्हें लागू करने में सक्षम होना चाहूंगा। ये इन्वेंट्री सिस्टम और डेटा के क्रमांकन के साथ भी संगत होना चाहिए।

मैं उत्तराधिकार का उपयोग नहीं करने की योजना बना रहा हूं , बल्कि एक इकाई-घटक / डेटा संचालित दृष्टिकोण। शुरू में मुझे लगा कि एक प्रणाली है:

  • बेसस्टैट: एक जेनेरिक क्लास जो आँकड़ों को रखती है (इसका इस्तेमाल वस्तुओं और चरित्र आँकड़ों के लिए भी किया जा सकता है)
  • आइटम: एक वर्ग जो डेटा रखता है जैसे कि सूची, नाम, आइटम टाइप और ऐसी चीजें जो ui, एक्शननाम, विवरण आदि से संबंधित हैं।
  • IWeapon: हथियार के लिए इंटरफ़ेस। हर हथियार का अपना वर्ग होगा IWeapon के साथ लागू किया गया। इसमें अटैक और चरित्र आँकड़ों का संदर्भ होगा। जब हथियार सुसज्जित होता है, तो यह डेटा (आइटम वर्ग 'स्टेट) वर्ण स्टेट में इंजेक्ट किया जाएगा (इसके पास जो भी बेसस्टैट है, यह स्टेटस क्लास में स्टेट बोनस के रूप में जोड़ा जाएगा) इसलिए उदाहरण के लिए, हम एक तलवार का उत्पादन करना चाहते हैं (सोच के लिए) JSON के साथ आइटम क्लासेस का निर्माण करें) इसलिए तलवार कैरेक्टर स्टैटस में 5 अटैक करेगी । इसलिए हमारे पास एक बेसस्टैट है ("हमला", 5) (हम एनम का उपयोग भी कर सकते हैं)। इस स्टेट को कैरेक्टर के "अटैक" स्टेट में एक बोनसस्टैट के रूप में जोड़ा जाएगा (जो एक अलग वर्ग होगा)। तो एक वर्ग जिसका नाम Sword implements है IWeapon बनाया जाएगा जब वह 'आइटम वर्ग बनाया गया है। इसलिए हम इंजेक्षन कर सकते हैं चरित्र आँकड़े इस तलवार में है और जब हमला, यह कुल प्राप्त कर सकते हैं हमला से स्टेट चरित्र स्टेट और हमला विधि में दण्ड क्षति।
  • बोनसस्टैट: बेसस्टैट को छूने के बिना सांख्यिकी को बोनस के रूप में जोड़ने का एक तरीका है।
  • IConsumable: IWeapon के समान तर्क। प्रत्यक्ष प्रतिमा जोड़ना काफी आसान है (+15 hp) लेकिन मैं इस सेटअप के साथ अस्थायी हथियार जोड़ने के बारे में निश्चित नहीं हूं (% x 5 मिनट के लिए हमला करने के लिए)।
  • IUpgradeable: इसे इस सेटअप के साथ लागू किया जा सकता है। मैं UpgradLevel को आधार स्टेट के रूप में सोच रहा हूं , जिसे हथियार को अपग्रेड करने पर बढ़ाया जाता है। उन्नत होने पर, हम अपने अपग्रेड स्तर से मिलान करने के लिए हथियार के बेसस्टैट की फिर से गणना कर सकते हैं ।

इस बिंदु तक, मैं देख सकता हूं कि यह प्रणाली काफी अच्छी है। लेकिन अन्य सुविधाओं के लिए, मुझे लगता है कि हमें कुछ और चाहिए, क्योंकि उदाहरण के लिए मैं इसमें क्राफ्टेबल फीचर को लागू नहीं कर सकता क्योंकि मेरा बेसस्टैट इस फीचर को हैंडल नहीं कर पाएगा और यहीं पर मैं फंस गया। मैं एक स्टैट के रूप में सभी अवयवों को जोड़ सकता हूं लेकिन इसका कोई मतलब नहीं होगा।

आपके लिए यह योगदान देना आसान बनाने के लिए, यहाँ कुछ प्रश्न दिए गए हैं जिनकी आप मदद कर सकते हैं:

  • क्या मुझे अन्य सुविधाओं को लागू करने के लिए इस सेटअप के साथ जारी रखना चाहिए? क्या यह विरासत के बिना संभव होगा?
  • क्या कोई ऐसा तरीका है जिसके बारे में आप सोच सकते हैं, इन सभी विशेषताओं को विरासत के बिना लागू करने के लिए?
  • आइटम संशोधक के बारे में, कि कोई कैसे प्राप्त कर सकता है? क्योंकि यह प्रकृति में बहुत सामान्य है।
  • इस तरह की वास्तुकला, किसी भी सिफारिशों के निर्माण की प्रक्रिया को आसान बनाने के लिए क्या किया जा सकता है?
  • क्या कोई स्रोत है जो मैं खोद सकता हूं जो इस समस्या से संबंधित है?
  • मैं वास्तव में विरासत से बचने की कोशिश करता हूं, लेकिन क्या आपको लगता है कि इनका समाधान किया जाएगा / इसे आसानी से बनाए रखा जा सकता है, जबकि इसे आसानी से बनाए रखा जा सकता है?

केवल एक प्रश्न का उत्तर देने के लिए स्वतंत्र महसूस करें क्योंकि मैंने प्रश्नों को बहुत विस्तृत रखा है ताकि मैं विभिन्न पहलुओं / लोगों से ज्ञान प्राप्त कर सकूं।


संपादित करें


@ Jjimenezg93 के उत्तर के बाद, मैंने परीक्षण के लिए C # में एक बहुत ही बुनियादी प्रणाली बनाई, यह काम करता है! देखें कि क्या आप इसमें कुछ भी जोड़ सकते हैं:

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);
}

अब तक, IItem और IAttribute आधार इंटरफेस हैं। संदेश के लिए आधार इंटरफ़ेस / विशेषता रखने के लिए कोई आवश्यकता नहीं थी (जो मैं सोच सकता हूं), इसलिए हम सीधे एक परीक्षण संदेश वर्ग बनाएंगे। अब परीक्षण कक्षाओं के लिए:


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);
    }
} 

ये जरूरी सेटअप हैं। अब हम सिस्टम का उपयोग कर सकते हैं (निम्नलिखित एकता के लिए है)।

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);
    }

}

इस TestManager स्क्रिप्ट को दृश्य में एक घटक में संलग्न करें और आप डिबग में देख सकते हैं कि संदेश सफलतापूर्वक पारित हो गया है।


चीजों को समझाने के लिए: खेल में प्रत्येक आइटम IItem इंटरफ़ेस को लागू करेगा और प्रत्येक गुण (नाम आपको भ्रमित नहीं करना चाहिए, इसका मतलब है कि आइटम सुविधा / प्रणाली। अपग्रेड करने योग्य, या अस्वीकार्य) IAttribute को लागू करेगा। फिर हमारे पास संदेश को संसाधित करने की एक विधि है (हमें संदेश की आवश्यकता क्यों है, इसे आगे के उदाहरण में समझाया जाएगा)। तो संदर्भ में, आप एक आइटम के लिए विशेषताएँ संलग्न कर सकते हैं और बाकी को आपके लिए कर सकते हैं। जो बहुत लचीला है, क्योंकि आप आसानी से विशेषताओं को जोड़ / हटा सकते हैं। इसलिए एक छद्म उदाहरण को अस्वीकार्य माना जाएगा। हमारे पास Disenchantable (IAttribute) नामक एक वर्ग होगा और यह Disenchant मेथड में होगा, यह इसके लिए पूछेगा:

  • सूची सामग्री (जब आइटम को अस्वीकृत किया जाता है, तो कौन सा आइटम खिलाड़ी को दिया जाना चाहिए) नोट: IItem को आइटमटाइप, आइटमआईडी आदि के लिए बढ़ाया जाना चाहिए।
  • int resultModifier (यदि आप एक प्रकार की प्रोत्साहन सुविधा को लागू करते हैं, तो आप असंतुष्ट होने पर प्राप्त सामग्री को बढ़ाने के लिए एक इंट पास कर सकते हैं)
  • इंट फेलचैंस (यदि असंतुष्ट प्रक्रिया में विफलता की संभावना है)

आदि।

ये जानकारी DisenchantManager नामक एक वर्ग द्वारा प्रदान की जाएगी, यह आइटम प्राप्त करेगा और आइटम के अनुसार इस संदेश का निर्माण करेगा (आइटम के आइटम जब अस्वीकृत हो) और खिलाड़ी प्रगति (resultModifier और विफलताChance)। इस संदेश को पारित करने के लिए, हम एक DisenchantMessage क्लास बनाएंगे, जो इस संदेश के लिए एक निकाय के रूप में कार्य करेगा। इसलिए DisenchantManager एक DisenchantMessage को पॉप्युलेट करेगा और उसे आइटम पर भेजेगा। आइटम संदेश प्राप्त करेगा और इसे संलग्न गुण में से सभी को पास करेगा। चूंकि Disenchantable class का ReceiveMessage मेथड DisenchantMessage की तलाश करेगा, केवल Disenchantable विशेषता इस संदेश को प्राप्त करेगी और इस पर कार्य करेगी। आशा है कि यह मेरे लिए जितना कुछ स्पष्ट करता है :)।


1
आप कुछ उपयोगी में प्रेरणा मिल सकता है साहब के लिए में प्रयोग किया जाता संशोधक प्रणाली
DMGregory

@DMGregory अरे! लिंक के लिए धन्यवाद। हालांकि यह बहुत संसाधनपूर्ण लगता है, दुर्भाग्य से मुझे अवधारणा को समझने के लिए वास्तविक चर्चा की आवश्यकता है। और मैं वास्तविक बातचीत का पता लगाने की कोशिश करता हूं, जो दुर्भाग्य से जीडीसी वॉल्ट की सदस्य-केवल सामग्री है (एक वर्ष के लिए 495 डॉलर पागल है!)। (आप जीडीसी वॉल्ट सदस्यता, -
वंडरथुल

कैसे, वास्तव में, आपके "बेसस्टैट" की अवधारणा शिल्पकारी हथियारों को रोक देगी?
अटैकफार्म

यह वास्तव में नहीं है, लेकिन वास्तव में मेरे दिमाग में संदर्भ में फिट नहीं है। "वुड", 2 और "आयरन", 5 को एक क्राफ्टिंग नुस्खा के लिए बेसस्टैट के रूप में जोड़ना उचित है, जो तलवार का उत्पादन करेगा। मुझे लगता है कि बेसस्टैट का नाम बदलकर बेसएट्रिब्यूट इस संदर्भ में बेहतर होगा। लेकिन फिर भी, सिस्टम उद्देश्य के लिए सेवा नहीं दे पाएगा। 5min -% 50 हमले की शक्ति के साथ उपभोज्य आइटम के बारे में सोचो। मैं इसे बेसस्टैट के रूप में कैसे पास करूंगा? "Perc_AttackPower", 50 को "यदि यह Perc है, तो पूर्णांक को प्रतिशत के रूप में मानें" और मिनटों की जानकारी गुम होने पर इसे हल करने की आवश्यकता है। ओ उम्मीद है कि तुम मुझे क्या मतलब है
वंडरथुल

@Attackfarm दूसरे विचार पर, इस "बेसस्टैट" अवधारणा को केवल एक इंट के बजाय किलों की सूची के साथ विस्तारित किया जा सकता है। इसलिए, उपभोग्य शौकीनों के लिए, मैं "हमला", 50, 5, 1 की आपूर्ति कर सकता हूं और IConsumable 3 पूर्णांक, 1. - मान, 2. - मिनट, 3. के लिए देखूंगा - अगर यह एक प्रतिशत है या नहीं। लेकिन यह अन्य प्रणालियों में हो जाता है और खुद को केवल समझाने के लिए मजबूर किया जाता है।
वंदार्थुल 15

जवाबों:


6

मुझे लगता है कि आप मूल विरासत और एक संदेश प्रणाली के साथ इकाई-घटक प्रणाली का उपयोग करके स्केलेबिलिटी और स्थिरता के संदर्भ में जो चाहें प्राप्त कर सकते हैं। बेशक, ध्यान रखें कि यह प्रणाली सबसे अधिक मॉड्यूलर / अनुकूलन योग्य / स्केलेबल है जिसके बारे में मैं सोच सकता हूं, लेकिन यह संभवतः आपके वर्तमान समाधान से भी बदतर प्रदर्शन करेगा।

मैं आगे समझाता हूँ:

सबसे पहले, आप एक इंटरफ़ेस IItemऔर एक इंटरफ़ेस बनाते हैं IComponent। कोई भी आइटम जिसे आप स्टोर करना चाहते हैं IItem, उसे इनहेरिट करना चाहिए , और जिस भी कंपोनेंट को आप अपने आइटमों से प्रभावित करना चाहते हैं, वह इनहेरिट करना होगा IComponent

IItemघटकों की एक सरणी और हैंडलिंग के लिए एक विधि होगी IMessage। यह हैंडलिंग विधि सभी संग्रहीत घटकों को केवल प्राप्त संदेश भेजता है। फिर, जो घटक उस दिए गए संदेश में रुचि रखते हैं, वे उसी के अनुसार कार्य करेंगे, और अन्य इसे अनदेखा करेंगे।

एक संदेश, उदाहरण के लिए, प्रकार की क्षति है, और यह हमलावर और हमले दोनों को सूचित करता है, इसलिए आप जानते हैं कि आपने कितना मारा और हो सकता है कि उस क्षति के आधार पर अपने रोष पट्टी को चार्ज करें। या दुश्मन का एआई चलाने का फैसला कर सकता है अगर यह आपको हिट करता है और 2HP से कम नुकसान करता है। ये गूंगे उदाहरण हैं, लेकिन इस प्रणाली के समान मैं इसका उल्लेख कर रहा हूं, आपको इस तरह के अधिकांश यांत्रिकी को जोड़ने के लिए एक संदेश बनाने और एप्रिप्टेट हैंडलिंग से अधिक कुछ भी करने की आवश्यकता नहीं होगी।

मेरे पास यहां मैसेजिंग के साथ ECS के लिए एक कार्यान्वयन है , लेकिन इसका उपयोग वस्तुओं के बजाय संस्थाओं के लिए किया जाता है और यह C ++ का उपयोग करता है। वैसे भी, मुझे लगता है कि यह मदद कर सकता है यदि आप एक नज़र डालें component.h, entity.hऔर messages.h। बहुत सी चीजों में सुधार किया जाना है लेकिन इसने मेरे लिए उस साधारण विश्वविद्यालय के काम में काम किया।

आशा है ये मदद करेगा।


हे @ jjimenezg93, आपके उत्तर के लिए धन्यवाद। तो आपके द्वारा बताए गए एक सरल उदाहरण के बारे में विस्तार से बताने के लिए: हम एक ऐसी तलवार चाहते हैं, जो है: - विनिमेय [घटक] - स्टेट मॉडिफायर [कंपोनेंट] - अपग्रेड करने योग्य [घटक] मेरे पास उन कार्यों की एक सूची है जो सभी चीजों की तरह हैं - DISENCHANT - MODIFY_STAT - UPGRADE जब भी आइटम इस संदेश को प्राप्त करता है, यह सभी घटकों के माध्यम से जाता है और इस संदेश को भेजता है, प्रत्येक घटक को पता होगा कि दिए गए संदेश के साथ क्या करना है। सिद्धांत रूप में, यह भयानक लगता है! मैंने आपका उदाहरण नहीं देखा, लेकिन मैं बहुत-बहुत धन्यवाद!
वंडरथुल

@ वंडरथुल हां, यह मूल रूप से विचार है। इस तरह, आइटम को इसके घटकों के बारे में कुछ भी नहीं पता होगा, इसलिए इसमें कोई युग्मन नहीं है और एक ही समय में, इसमें आपकी इच्छा के अनुसार सभी कार्यक्षमता होगी, जिसे विभिन्न प्रकार की वस्तुओं के बीच भी साझा किया जा सकता है। मुझे आशा है कि यह आपकी आवश्यकताओं को पूरा करता है!
jjimenezg93
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.