क्या मैं इस घटक वास्तुकला के साथ सही रास्ते पर हूं?


9

मैंने हाल ही में गहरी श्रेणी पदानुक्रमों से छुटकारा पाने और उन्हें विन्यास योग्य घटकों के साथ बदलने के लिए अपने गेम आर्किटेक्चर को फिर से बनाने का फैसला किया है। मैं जो पहली पदानुक्रम की जगह ले रहा हूं वह आइटम पदानुक्रम है और मैं यह जानना चाहूंगा कि क्या मैं सही रास्ते पर हूं।

पहले, मेरे पास एक पदानुक्रम था जो कुछ इस तरह से था:

Item -> Equipment -> Weapon
                  -> Armor
                  -> Accessory
     -> SyntehsisItem
     -> BattleUseItem -> HealingItem
                      -> ThrowingItem -> ThrowsAsAttackItem

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

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

यहाँ मैं घटक सेटअप के लिए वर्तमान में क्या सोच रहा हूँ:

मेरे पास एक बेस आइटम वर्ग है जिसमें विभिन्न घटकों (यानी एक उपकरण घटक स्लॉट, एक चिकित्सा घटक स्लॉट, आदि) और साथ ही मनमाने ढंग से घटकों के लिए एक नक्शा) के लिए स्लॉट हैं, इसलिए ऐसा कुछ है:

class Item
{
    //Basic item properties (name, ID, etc.) excluded
    EquipmentComponent* equipmentComponent;
    HealingComponent* healingComponent;
    SynthesisComponent* synthesisComponent;
    ThrowComponent* throwComponent;
    boost::unordered_map<std::string, std::pair<bool, ItemComponent*> > AdditionalComponents;
} 

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

मानचित्र का उपयोग उन मनमाने घटकों को संग्रहीत करने के लिए किया जाता है जो कोर आइटम घटक नहीं हैं। मैं यह इंगित करने के लिए एक बूल के साथ जोड़ रहा हूं कि क्या आइटम कंटेनर को ItemComponent का प्रबंधन करना चाहिए या यदि यह किसी बाहरी स्रोत द्वारा प्रबंधित किया जा रहा है।

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

मेरा सवाल यह है कि क्या यह एक अच्छा डिज़ाइन है? यदि नहीं, तो इसमें सुधार कैसे किया जा सकता है? मैंने सभी घटकों को मानचित्र में समूहीकृत करने पर विचार किया, लेकिन मुख्य आइटम घटकों के लिए स्ट्रिंग अनुक्रमण का उपयोग करना आवश्यक नहीं था

जवाबों:


8

यह एक बहुत ही उचित पहला कदम है।

आप सामान्यता ("अतिरिक्त घटक" मानचित्र) और लुकअप परफॉर्मेंस (हार्ड-कोडेड सदस्य) के संयोजन का विकल्प चुन रहे हैं, जो पूर्व-अनुकूलन का एक सा हो सकता है - स्ट्रिंग-आधारित की सामान्य अक्षमता के संबंध में आपकी बात लुक-अप अच्छी तरह से किया गया है, लेकिन आप इसे कम कर सकते हैं कि सूचकांक घटकों का चयन करके हैश में तेजी से कुछ करें। एक तरीका यह हो सकता है कि प्रत्येक कंपोनेंट टाइप को एक यूनिक टाइप आईडी (अनिवार्य रूप से आप लाइटवेट कस्टम आरटीआई लागू कर रहे हों ) और उसके आधार पर इंडेक्स दें।

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

आप हार्ड-कोडित घटकों में से प्रत्येक के "डमी" नो-ऑप संस्करण प्रदान करने पर विचार कर सकते हैं और यह सुनिश्चित कर सकते हैं कि वे हमेशा असाइन किए गए हैं - फिर आप पॉइंटर्स के बजाय संदर्भ सदस्यों का उपयोग कर सकते हैं, और आपको NULL पॉइंटर के लिए कभी भी जांच करने की आवश्यकता नहीं होगी हार्ड-कोडित घटक वर्गों में से एक के साथ बातचीत करने से पहले। आप अभी भी डायनामिक प्रेषण की लागत को उस घटक के सदस्यों के साथ बातचीत करने के लिए समझायेंगे, लेकिन सूचक सदस्यों के साथ भी ऐसा होगा। यह एक कोड स्वच्छता का मुद्दा है क्योंकि प्रदर्शन प्रभाव सभी संभावना में नगण्य होगा।

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

आपके दृष्टिकोण से मुझे जो बड़ा नुकसान हुआ है, वह यह है कि आप सभी घटकों को एक साथ "एंटिटी" ऑब्जेक्ट में दबा रहे हैं, जो वास्तव में हमेशा सबसे अच्छा डिज़ाइन नहीं होता है। से मेरी संबंधित जवाब एक और घटक आधारित सवाल का:

घटकों का एक बड़ा मानचित्र और गेम ऑब्जेक्ट में एक अपडेट () कॉल का उपयोग करने का आपका दृष्टिकोण काफी उप-इष्टतम है (और उन प्रकार के सिस्टम के पहले निर्माण के लिए एक आम नुकसान)। यह अपडेट के दौरान बहुत खराब कैश सुसंगतता के लिए बनाता है और आपको एक बार में डेटा या व्यवहार के बड़े बैचों के सिमड-स्टाइल प्रक्रिया की सहमति और प्रवृत्ति का लाभ लेने की अनुमति नहीं देता है। यह अक्सर डिज़ाइन का उपयोग करना बेहतर होता है जहां गेम ऑब्जेक्ट अपने घटकों को अपडेट नहीं करता है, बल्कि घटक के लिए जिम्मेदार सबसिस्टम स्वयं उन सभी को एक साथ अपडेट करता है।

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

लेकिन मैं इसे केवल भविष्य की दिशा के रूप में विचार करने के लिए कुछ के रूप में इंगित करता हूं - आप निश्चित रूप से इस अतिरंजना पर जाना नहीं चाहते हैं; आप निरंतर रिफैक्टरिंग के माध्यम से एक क्रमिक संक्रमण कर सकते हैं या आपको पता चल सकता है कि आपका वर्तमान कार्यान्वयन आपकी आवश्यकताओं को पूरी तरह से पूरा करता है और उस पर पुनरावृत्ति करने की कोई आवश्यकता नहीं है।


1
आइटम वस्तु से छुटकारा पाने का सुझाव देने के लिए +1। जबकि यह अधिक काम करेगा, यह एक बेहतर घटक प्रणाली का उत्पादन करेगा।
जेम्स

मेरे पास कुछ और सवाल थे, अनिश्चित यदि मैं नया टॉपिउक शुरू करूं, तो सबसे पहले यहां प्रयास करना चाहिए: मेरे आइटम वर्ग के लिए, ऐसी कोई विधि नहीं है जिसे मैं ईवर्ट फ्रेम (या यहां तक ​​कि करीब) कहूं। मेरे ग्राफिक्स सबसिस्टम के लिए, मैं आपकी सलाह लूंगा और सिस्टम के तहत अपडेट करने के लिए सभी ऑब्जेक्ट रखूंगा। मेरे पास दूसरा प्रश्न यह है कि मैं घटक जाँच कैसे करूँ? उदाहरण के लिए, मैं देखना चाहता हूं कि क्या मैं X के रूप में एक आइटम का उपयोग कर सकता हूं, इसलिए स्वाभाविक रूप से मैं यह देखने के लिए जांच करूंगा कि क्या आइटम में एक्स को निष्पादित करने के लिए आवश्यक घटक है। क्या यह ऐसा करने का सही तरीका है? जवाब के लिए फिर से धन्यवाद
user127817
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.