भारी ओओपी बनाम शुद्ध इकाई घटक सिस्टम? [बन्द है]


13

मैं स्वीकार करता हूं, मैंने अति प्रयोग और यहां तक ​​कि विरासत का दुरुपयोग करने का पाप किया है। पहला (टेक्स्ट) गेम प्रोजेक्ट जो मैंने तब बनाया था जब मैं अपना OOP कोर्स ले रहा था, "डोर" और "अनलॉक डोर" से "डोर" और "रूम विद वन डोर", "रूम विद टू डोर", और इसलिए "रूम" से।

ग्राफिकल) गेम के साथ मैंने हाल ही में काम किया, मुझे लगा कि मैंने अपना सबक सीखा है और विरासत का उपयोग करने की एक सीमा रखी है। हालाँकि मैंने देखा कि समस्याएं जल्द ही सामने आने लगी हैं। मेरा जड़ वर्ग अधिक से अधिक प्रस्फुटित होने लगा था, और मेरा पत्ता वर्ग डुप्लिकेट कोड से भरा हुआ था।

मुझे लगा कि मैं अभी भी चीजें गलत कर रहा हूं, और इसे ऑनलाइन देखने के बाद मुझे पता चला कि मैं इस समस्या के साथ अकेला नहीं था। यह है कि मैंने कुछ गहन शोध के बाद एंटिटी सिस्टम की खोज कैसे की (पढ़ें: googlefu)

जब मैंने इस पर पढ़ना शुरू किया, तो मैं यह देख पा रहा था कि घटकों के साथ पारंपरिक ओओपी पदानुक्रम के साथ होने वाली समस्याओं को हल करने में यह कितना स्पष्ट रूप से सक्षम था। हालाँकि पहले रीडिंग में ये थे। जब मैं और अधिक ... "कट्टरपंथी" ईएस दृष्टिकोण पर ठोकर खाई, जैसे कि टी-मशीन पर एक ।

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

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

निम्नलिखित उदाहरण से पता चलता है कि मेरा क्या मतलब है (यह गेम इंजन आर्किटेक्चर, अध्याय 14 में पाए गए एक उदाहरण से प्रेरित है)।

मेरे पास वाहनों के लिए एक छोटा पेड़ होगा। रूट वाहन वर्ग में एक रेंडरिंग घटक, एक टक्कर घटक, स्थिति घटक आदि होगा।

फिर एक टैंक, वाहन का एक उपवर्ग इसमें से उन घटकों को प्राप्त करेगा, और इसे स्वयं "तोप" घटक दिया जाएगा।

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

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

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

आपके विचार?

पुनश्च: मैं जावा का उपयोग कर रहा हूं, इसलिए सामान्य घटकों का उपयोग करने के बजाय इसे लागू करने के लिए कई विरासत का उपयोग करना संभव नहीं है।

PPS: इंटरकम्पॉर्टेंट संचार एक दूसरे पर निर्भर घटकों को जोड़कर किया जाएगा। यह युग्मन को जन्म देगा, लेकिन मुझे लगता है कि यह एक अच्छा व्यापार है।


2
यह सब मुझे ठीक लगता है। क्या आपकी पदानुक्रम या इकाई प्रणाली में एक विशिष्ट उदाहरण है जो आपको "बदबू आती है"? अंत में, यह सब पवित्रता के कुछ अर्थों से अधिक खेल को पूरा करने के बारे में है।
drhayes

मैं नहीं करता, लेकिन जैसा मैंने कहा, मेरे पास मुश्किल से कोई अनुभव है और मैं इसके लिए सबसे अच्छे न्यायाधीश से बहुत दूर हूं।
मिडोरी रियू

3
मैंने इस प्रश्न को बंद करने के लिए मतदान किया है क्योंकि यह व्यक्तिपरक है और व्यापक चर्चा के लिए खुला है। मैं इसकी सराहना करता हूं कि यह एक ईमानदार स्थिति से पूछा गया था - लेकिन यहां कैसे आगे बढ़ना है यह चुनना पूरी तरह से व्यक्तिगत राय का विषय है। एक उपवर्ग में अपने घटकों को ठीक करने का एकमात्र वास्तविक पहलू यह है कि घटकों की व्यवस्था रनटाइम में परिवर्तनशील नहीं है - लेकिन यह निश्चित रूप से आपके लिए स्पष्ट होना चाहिए और यह एक विकल्प है जो आप बनाते हैं।
काइलोटन

4
मैंने भी बंद करने के लिए मतदान किया। यह एक अच्छा और अच्छा लिखित प्रश्न है, लेकिन जीडीएसई के लिए उपयुक्त नहीं है। आप GameDev.net पर इसे रीपोस्ट करने की कोशिश कर सकते हैं।
शॉन मिडिलडाइच

जैसा कि लिखा गया है, इस सवाल के साथ कि 'आपकी राय?', यह वास्तव में खुला-अंत है और अचूक है। हालांकि, यह है जवाबदेह यदि आप के रूप में अगर यह सवाल था कि इसका जवाब 'वहाँ है कि मैं देख के बिना में गिर सकता है कर रहे हैं किसी भी भारी जाल?' (कम से कम, अगर आपको लगता है कि वास्तव में विभिन्न आर्किटेक्चर के बीच कोई अनुभवजन्य अंतर है।)
जॉन कलस्बेक

जवाबों:


8

इस उदाहरण पर विचार करें:

आप एक आरटीएस बना रहे हैं। पूर्ण तर्क के एक फिट में, आप एक बेस क्लास बनाने का फैसला करते हैं GameObject, और फिर दो उपवर्ग, Buildingऔर Unit। यह ठीक काम करता है, ज़ाहिर है, और आप कुछ इस तरह दिखता है:

  • GameObject
    • ModelComponent
    • CollisionComponent
    • ...
  • Building
    • ProductionComponent
    • ...
  • Unit
    • AimingAIComponent
    • WeaponComponent
    • ParticleEmitterComponent
    • AnimationComponent
    • ...

अब आप के प्रत्येक उपवर्ग में Unitपहले से ही सभी घटक हैं जिनकी आपको आवश्यकता है। और एक बोनस के रूप में, आपके पास उस थकाऊ सेटअप कोड को रखने के लिए एक ही जगह newहै WeaponComponent, जो एक है , उसे एक AimingAIComponentऔर एक- से-एक से जोड़ता है ParticleEmitterComponent!

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

और अब, आप कितनी दूरदर्शिता के आधार पर, आप सूक्ष्म कीड़े के साथ समाप्त हो सकते हैं या नहीं हो सकते हैं। पता चलता है कि खेल में कहीं और कुछ कोड हो सकता है जो इस तरह दिखता है:

if (myGameObject instanceof Unit)
    doSomething(((Unit)myGameObject).getWeaponComponent());

वह चुपचाप आपके Towerभवन के लिए काम नहीं करता , भले ही आप वास्तव में यह चाहते थे कि वह किसी हथियार के साथ काम करे। अब इसे कुछ इस तरह देखना होगा:

WeaponComponent weapon = myGameObject.getComponent(WeaponComponent.class);
if (weapon)
    doSomething(weapon);

काफी बेहतर! आपके द्वारा इसे बदलने के बाद ऐसा होता है कि आपके द्वारा लिखा गया कोई भी एक्सेसरी मेथड इस स्थिति में समाप्त हो सकता है। तो सबसे सुरक्षित बात यह है कि उन सभी को हटा दें, और इस एक विधि के माध्यम से हर घटक का उपयोग करें getComponent, जो किसी भी उपवर्ग के साथ काम कर सकता है। (वैकल्पिक रूप से, आप हर एक प्रकार के get*Component()सुपरक्लास को जोड़ सकते हैं GameObjectऔर घटक को वापस करने के लिए उप-वर्ग में उन्हें ओवरराइड कर सकते हैं। मैं पहले वाले को मान लूंगा, हालांकि।)

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

यदि आप चरम सीमा तक इसका अनुसरण करते हैं, तो आप हमेशा अपने उपवर्गों को पूरी तरह से घटकों के अक्रिय बैग बनाते हैं, जिस बिंदु पर आसपास उपवर्ग होने का कोई भी बिंदु नहीं होता है। आप लगभग सभी एक साथ एक वर्ग पदानुक्रम जाने का लाभ प्राप्त कर सकते हैं विधि पदानुक्रम कि उचित घटकों पैदा करता है। Unitक्लास होने के बजाय , आपके पास एक addUnitComponentsतरीका है जो एक बनाता है AnimationComponentऔर एक कॉल भी करता है addWeaponComponents, जो AimingAIComponentWeaponComponent, ए और ए बनाता है ParticleEmitterComponent। परिणाम यह है कि आपको एक इकाई प्रणाली के सभी लाभ हैं, सभी कोड एक पदानुक्रम का पुन: उपयोग करते हैं, और instanceofआपके वर्ग प्रकार की जांच या डाली जाने का कोई भी प्रलोभन नहीं है ।


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

वाह आपकी पोस्ट पढ़कर मुझे बुरा सपना आया! बेशक, मेरा मतलब है कि एक अच्छे तरीके से, जैसा कि आपने मेरी आँखें खोलीं कि मैं किस तरह के दुःस्वप्न के साथ समाप्त हो सकता हूं! काश मैं इस तरह के एक विस्तृत जवाब के लिए और अधिक जवाब दे सकता, लेकिन वास्तव में जोड़ने के लिए बहुत कुछ नहीं है!
मिडोरी रियू

अधिक सरल तरीके से। आप इनहेरिटेंस का उपयोग गरीब आदमी के कारखाने पैटर्न के रूप में करते हैं।
जरदोज़ो

2

वंशानुक्रम पर रचना OOP शब्दावली है (कम से कम जिस तरह से मैंने सीखा / सिखाया गया था)। रचना और विरासत के बीच चुने जाने के लिए आप कहते हैं कि "कार एक प्रकार का पहिया है" (विरासत) और "कार में पहिए हैं" (रचना)। एक को दूसरे की तुलना में अधिक सही ध्वनि चाहिए (इस मामले में रचना), और यदि आप तय नहीं कर सकते, तो रचना के लिए डिफ़ॉल्ट जब तक आप अन्यथा निर्णय नहीं लेते।


1

जब गेम के ऑब्जेक्ट्स के आधार पर मौजूदा गेम्स के कंपोनेंट बेस्ड सिस्टम को इंटीग्रेट करने की बात आती है, तो काउबॉय प्रोग्रामिंग पर एक लेख है http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ जो आपको कुछ संकेत दे सकता है। जिस तरह से परिवर्तन किया जा सकता है।

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

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

एक घटक आधारित दृष्टिकोण के साथ खेल की वस्तुओं का मिश्रण मिश्रण दोनों दृष्टिकोणों से कमियां के साथ घटक आधारित दृष्टिकोण के कुछ फायदे लाता है।

यह आपके काम आ सकता है। लेकिन मैं संक्रमण काल ​​के बाहर दोनों को एक वास्तुकला से दूसरे वास्तुकला में नहीं मिलाता।

PS एक फोन पर लिखा है, इसलिए मेरे पास बाहरी संसाधनों को जोड़ने के लिए एक कठिन समय है।


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

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