खेल संस्थाओं के विनाश को संभालने का उचित तरीका


10

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

जोड़ते समय मैं नई इकाई को पीछे धकेल सकता हूं, मुझे कंटेनर में कहीं भी निकालने की आवश्यकता हो सकती है। हटाने के लिए अपनी स्थिति खोजने के लिए तत्व को खोजने से बचने के लिए, मेरे पास क्या विकल्प हैं?

मैंने सोचा कि मैं इकाई आईडी को कंटेनर में अपनी स्थिति के रूप में संग्रहीत कर सकता हूं, प्रत्यक्ष हटाने के लिए एक रास्ता बना सकता हूं, लेकिन क्या यह किसी प्रकार की पारस्परिक निर्भरता 'विकार' उत्पन्न करेगा?

मुझे पता है कि सही तरीका कुछ होगा जैसे List.RemoveAt (whereToRemove); लेकिन क्या होगा यदि केवल इकाई को पता है कि उसे कब मरना चाहिए?

या मैं सिर्फ कुछ याद कर रहा हूं और एक सूची कंटेनर को पता चलेगा कि कोई वस्तु नष्ट हो गई है और अपना आकार कम कर रहा है?

जवाबों:


10

यहां आपकी शर्तें हैं:

  • अन्य ऑब्जेक्ट अभी भी आपके निकाले गए निकाय पर निर्भर हो सकते हैं, इसे निकालने के बाद।

  • आप केवल इकाई को यह निर्दिष्ट करने के लिए चाहते हैं कि यह स्वयं को हटाने के लिए है।

आपके पास दोनों नहीं हो सकते। क्यों? क्योंकि आपकी इकाई की तुलना में उच्च स्तर पर कोड स्वयं (नीचे के उदाहरण देखें) यह तय करता है कि उस इकाई का उपयोग कब किया जाना है। नतीजतन, केवल उसी स्तर पर कोड यह निर्धारित कर सकता है कि आपकी इकाई हटाने के लिए फिट है या नहीं।

हालाँकि , ऐसा क्या हो सकता है कि कोई घटना जो उच्च स्तर के कोड के लिए सुन रहा है, उसे बंद करके इकाई स्वयं हटाने का अनुरोध कर सकती है । यह उच्च स्तर तब एक सूची में हटाने के लिए इस अनुरोध को संग्रहीत करता है।


उदाहरण 1: घटनाओं के बिना

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

हम बी के साथ टकराव के लिए ए की जांच करते हैं। एक टक्कर है। A को 50% क्षति होती है।

हम सी के साथ टकराव के लिए ए की जांच करते हैं। एक टक्कर है। A को 50% क्षति होती है। क्योंकि क्षति 0 तक पहुंचती है, ए निर्धारित करता है कि यह "मर गया" है। यह सूची से खुद को हटा देता है।

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

उदाहरण 2: घटनाओं के साथ

पहले की तरह ही सेटअप।

हम बी के साथ टकराव के लिए ए की जांच करते हैं। एक टक्कर है। A को 50% क्षति होती है।

हम सी के साथ टकराव के लिए ए की जांच करते हैं। एक टक्कर है। A को 50% क्षति होती है। क्योंकि क्षति 0 तक पहुंचती है, ए निर्धारित करता है कि यह "मर गया" है। यह इकाई प्रबंधन कोड के लिए एक घटना कहता है, "मुझे ASAP निकालें"। इकाई प्रबंधन कोड घटना के हिस्से के रूप में भेजे गए इकाई संदर्भ को देखता है, और निकाले जाने वाली संस्थाओं की सूची में उस संदर्भ को संग्रहीत करता है।

हम डी के साथ टकराव के लिए ए की जांच करते हैं। कोई टक्कर नहीं है, और चेक ठीक काम करता है।

अब, वर्तमान गेम लूप पुनरावृत्ति के बहुत अंत में , निकाले जाने वाली संस्थाओं की सूची के माध्यम से चलाएं, और इनमें से प्रत्येक को अपनी मुख्य संस्थाओं की सूची से हटा दें।


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

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

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


0

आप निश्चित रूप से एक HashMap / HashTable की तलाश कर रहे हैं । हैशटेबल एक मानचित्र है जो एक विशिष्ट मूल्य की कुंजी से मेल खाता है। कुंजी कुछ भी हो सकती है (जैसे कि एंटिटी आईडी)।


0

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

कुछ मामलों में आपको अपने गेम की सभी वस्तुओं पर पुनरावृति करने के लिए एक सूची की आवश्यकता होती है। यह सूची केवल एक लिंक सूची हो सकती है, जिसमें वस्तुओं को सम्मिलित करने और हटाने से ओ (1) समय बिल्कुल लगेगा।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.