मुझे यकीन नहीं है कि आप अभी भी इसे पढ़ रहे हैं लेकिन मैं लंबे समय से इस तरह की समस्या से जूझ रहा हूं।
मैंने कई तरह की प्रभावित प्रणालियों को डिज़ाइन किया है। मैं अब संक्षेप में उनके ऊपर जाऊंगा। यह सब मेरे अनुभव पर आधारित है। मैं सभी उत्तरों को जानने का दावा नहीं करता।
स्थैतिक संशोधक
इस प्रकार की प्रणाली ज्यादातर किसी भी संशोधनों को निर्धारित करने के लिए सरल पूर्णांकों पर निर्भर करती है। उदाहरण के लिए, +100 से अधिकतम एचपी, +10 हमला करने के लिए और इसी तरह। यह प्रणाली पर्केंट्स को भी संभाल सकती है। आपको बस यह सुनिश्चित करने की आवश्यकता है कि स्टैकिंग नियंत्रण से बाहर न हो।
मैंने वास्तव में इस प्रकार की प्रणाली के लिए उत्पन्न मूल्यों को कैश नहीं किया है। उदाहरण के लिए, यदि मैं किसी चीज का अधिकतम स्वास्थ्य प्रदर्शित करना चाहता था, तो मैं मौके पर मूल्य उत्पन्न कर सकता था। यह चीजों को त्रुटि प्रवण होने से रोकता है और इसमें शामिल सभी लोगों के लिए समझने में आसान है।
(मैं जावा में काम करता हूं, इसलिए जो जावा आधारित है, लेकिन उसे अन्य भाषाओं के लिए कुछ संशोधनों के साथ काम करना चाहिए) यह प्रणाली आसानी से संशोधन प्रकारों और फिर पूर्णांक के लिए एनमों का उपयोग करके किया जा सकता है। अंतिम परिणाम को किसी प्रकार के संग्रह में रखा जा सकता है जिसमें कुंजी, मूल्य आदेशित जोड़े हों। यह तेजी से लुकअप और गणना होगी, इसलिए प्रदर्शन बहुत अच्छा है।
कुल मिलाकर, यह सिर्फ स्टैटिक मॉडिफायर को फ्लैट करने के साथ बहुत अच्छा काम करता है। हालाँकि, कोड का उपयोग किए जाने वाले संशोधक के लिए उचित स्थानों में मौजूद होना चाहिए: getAttack, getMaxHP, getMeleeDamage, और इसी तरह आगे।
जहां यह विधि विफल हो जाती है (मेरे लिए) बफ़र्स के बीच बहुत जटिल बातचीत है। वहाँ एक वास्तविक आसान तरीका नहीं है, यह थोड़ा ऊपर ghettoing को छोड़कर बातचीत है। इसमें कुछ सरल बातचीत की संभावनाएं हैं। ऐसा करने के लिए, आपको स्थिर संशोधक को स्टोर करने के तरीके में संशोधन करना होगा। कुंजी के रूप में एक एनम का उपयोग करने के बजाय, आप स्ट्रिंग का उपयोग करते हैं। यह स्ट्रिंग Enum नाम + अतिरिक्त चर होगा। 10 में से 9 बार, अतिरिक्त चर का उपयोग नहीं किया जाता है, इसलिए आप अभी भी कुंजी के रूप में एनम नाम को बनाए रखते हैं।
चलो एक त्वरित उदाहरण करते हैं: यदि आप मरे हुए प्राणियों के खिलाफ क्षति को संशोधित करने में सक्षम होना चाहते हैं, तो आप इस तरह की एक जोड़ी जोड़ी हो सकते हैं: (DAMAGE_Undead, 10) डैमेज एनम है और अंडरड अतिरिक्त चर है। तो अपने युद्ध के दौरान, आप कुछ ऐसा कर सकते हैं:
dam += attacker.getMod(Mod.DAMAGE + npc.getRaceFamily()); //in this case the race family would be undead
वैसे भी, यह काफी अच्छी तरह से काम करता है और तेज है। लेकिन यह जटिल इंटरैक्शन और हर जगह "विशेष" कोड होने में विफल रहता है। उदाहरण के लिए, "मौत पर टेलीपोर्ट करने के 25% मौके" की स्थिति पर विचार करें। यह एक "काफी" जटिल है। उपरोक्त प्रणाली इसे संभाल सकती है, लेकिन आसानी से नहीं, जैसा कि आपको निम्नलिखित की आवश्यकता है:
- निर्धारित करें कि क्या खिलाड़ी के पास यह मॉड है।
- कहीं, सफल होने पर टेलीपोर्टेशन निष्पादित करने के लिए कुछ कोड हैं। इस कोड का स्थान अपने आप में एक चर्चा है!
- मॉड मैप से सही डेटा प्राप्त करें। मूल्य का क्या अर्थ है? क्या यह वह कमरा है जहाँ वे टेलीपोर्ट करते हैं? अगर किसी खिलाड़ी के पास दो टेलीपोर्ट मॉड हैं तो क्या होगा ?? राशियों को एक साथ नहीं जोड़ा जाएगा ?????? विफलता!
तो यह मेरे अगले एक के लिए मुझे लाता है:
परम जटिल बफ़ सिस्टम
मैंने एक बार खुद से 2 डी MMORPG लिखने की कोशिश की। यह एक बहुत बड़ी गलती थी लेकिन मैंने बहुत कुछ सीखा!
मैंने 3 बार प्रभावित प्रणाली को फिर से लिखा। पहले वाले ने ऊपर के कम शक्तिशाली बदलाव का इस्तेमाल किया। दूसरा वह था जो मैं बात करने जा रहा हूं।
इस प्रणाली में प्रत्येक संशोधन के लिए कक्षाओं की एक श्रृंखला थी, इसलिए चीजें जैसे: ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent। मेरे पास इन लोगों का एक मिलियन था - यहां तक कि TeleportOnDeath जैसी चीजें भी।
मेरी कक्षाओं में ऐसी चीजें थीं जो निम्नलिखित कार्य करेंगी:
- applyAffect
- removeAffect
- checkForInteraction <--- महत्वपूर्ण
लागू करें और अपने आप को समझाएं (हालांकि गड़बड़ी जैसी चीजों के लिए, यह प्रभावित करेगा कि यह सुनिश्चित करने के लिए कि एचपी ने कितना बढ़ाया है, जब यह प्रभावित होता है, तो यह केवल उस राशि को हटा देगा जो यह जोड़ा गया था। यह छोटी गाड़ी, योग्य, और था। मुझे यह सुनिश्चित करने के लिए एक लंबा समय लगा कि यह सही था। मुझे अभी भी इसके बारे में अच्छी भावना नहीं मिली है।)।
CheckForInteraction विधि कोड का एक भयानक जटिल टुकड़ा था। प्रत्येक प्रभावित (यानी: चेंजएचपी) कक्षाओं में, यह निर्धारित करने के लिए कोड होगा कि क्या इसे इनपुट प्रभावित द्वारा संशोधित किया जाना चाहिए। तो उदाहरण के लिए, यदि आपके पास कुछ ऐसा था ...।
- बफ़ 1: हमले पर 10 आग से हुए नुकसान
- बफ़ 2: सभी आग से होने वाली क्षति को 25% बढ़ाता है।
- बफ़ 3: 15 से सभी आग क्षति को बढ़ाता है।
CheckForInteraction विधि इन सभी प्रभावों को संभालती है। ऐसा करने के लिए, पास के सभी खिलाड़ियों पर प्रत्येक को प्रभावित करना पड़ता है !! इसका कारण यह है कि मैंने एक क्षेत्र में कई खिलाड़ियों को प्रभावित किया है। इसका मतलब यह है कि ऊपर दिए गए किसी भी विशेष कथनों में कोड कभी भी शामिल नहीं होता है - "अगर हमारी मृत्यु हो गई, तो हमें मृत्यु पर टेलीपोर्ट की जांच करनी चाहिए"। यह प्रणाली सही समय पर अपने आप इसे सही ढंग से संभाल लेगी।
इस प्रणाली को लिखने की कोशिश मुझे 2 महीने की तरह लगी और कई बार सिर फट गया। फिर भी, यह वास्तव में शक्तिशाली था और सामान की एक पागल राशि कर सकता था - खासकर जब आप मेरे खेल में क्षमताओं के लिए निम्नलिखित दो तथ्यों को ध्यान में रखते हैं: 1. उनके पास लक्ष्य सीमाएं थीं (यानी: एकल, स्वयं, केवल समूह, PB AE आत्म , पीबी एई लक्ष्य, लक्षित एई, और इसी तरह)। 2. क्षमताएँ उन पर 1 से अधिक प्रभाव डाल सकती हैं।
जैसा कि मैंने ऊपर उल्लेख किया है, यह इस खेल के लिए 3 डी प्रभावित प्रणाली का दूसरा था। मैं इससे दूर क्यों चला गया?
इस प्रणाली का अब तक का सबसे खराब प्रदर्शन था! यह बहुत धीमी गति से था क्योंकि इसमें प्रत्येक चीज़ के लिए इतनी अधिक जाँच करनी होती थी। मैंने इसे बेहतर बनाने की कोशिश की, लेकिन इसे विफल माना।
इसलिए हम अपने तीसरे संस्करण में आते हैं (और एक अन्य प्रकार की बफ़र प्रणाली):
हैंडलर के साथ जटिल प्रभावित वर्ग
तो यह पहले दो का एक बहुत संयोजन है: हम एक प्रभावित वर्ग में स्थिर चर हो सकते हैं जिसमें बहुत अधिक कार्यक्षमता और अतिरिक्त डेटा होता है। फिर बस हैंडलर को बुलाओ (मेरे लिए, विशिष्ट कार्यों के लिए उपवर्गों के बजाय बहुत कुछ स्थैतिक उपयोगिता विधियां। लेकिन मुझे यकीन है कि अगर आप भी कुछ करना चाहते हैं तो आप कार्यों के लिए उपवर्गों के साथ जा सकते हैं)।
प्रभावित वर्ग में सभी रसदार अच्छी चीजें होंगी, जैसे लक्ष्य प्रकार, अवधि, उपयोग की संख्या, निष्पादित करने का मौका और इसी तरह आगे।
हमें अभी भी स्थितियों को संभालने के लिए विशेष कोड जोड़ना होगा, उदाहरण के लिए, मौत पर टेलीपोर्ट। हमें अभी भी युद्धक कोड में इसके लिए मैन्युअल रूप से जांच करनी होगी, और फिर यदि यह अस्तित्व में है, तो हमें प्रभावितों की एक सूची मिलेगी। प्रभावितों की इस सूची में वर्तमान में लागू किए गए सभी प्रभावित खिलाड़ी हैं जो मौत पर टेलीपोर्टिंग से निपटते हैं। तब हम बस एक-एक को देखेंगे और यह देखेंगे कि क्या यह निष्पादित हुआ और सफल रहा (हम पहले सफल व्यक्ति पर रोक देंगे)। यह सफल था, हम केवल हैंडलर को इस बात का ध्यान रखने के लिए कहेंगे।
इंटरेक्शन किया जा सकता है, अगर आप भी चाहते हैं। यह खिलाड़ियों / आदि पर विशिष्ट बफ़्स देखने के लिए कोड लिखना होगा। क्योंकि इसमें अच्छा प्रदर्शन है (नीचे देखें), इसे करने के लिए काफी कुशल होना चाहिए। यह सिर्फ और अधिक जटिल हैंडलर और इतने पर की आवश्यकता होगी।
तो इसमें पहली प्रणाली का प्रदर्शन बहुत अधिक है और अभी भी दूसरी (बहुत अधिक नहीं) जैसी दूसरी जटिलता है। जावा में कम से कम, आप MOST मामलों में लगभग पहले वाले (यानी: enum map ( http://docs.oracle.com/javase/6/docs/api/java) होने के लिए कुछ मुश्किल काम कर सकते हैं। Enut के साथ /util/EnumMap.html ) मानों के रूप में प्रभावित करता है और ArrayList के रूप में। यह आपको यह देखने की अनुमति देता है कि क्या आप जल्दी से प्रभावित करते हैं [क्योंकि सूची 0 होगी या मानचित्र में एनम नहीं होगा] और नहीं बिना किसी कारण के खिलाड़ी की प्रभावित सूचियों पर लगातार पुनरावृत्ति करना। मुझे इस बात से कोई फर्क नहीं पड़ता कि यदि इस समय हमें उनकी आवश्यकता है तो मैं इसे प्रभावित करूँगा। यदि बाद में यह समस्या बन जाती है तो मैं इसका अनुकूलन करूंगा।)
मैं वर्तमान में फिर से खोल रहा हूं (फास्टट्रॉम कोड आधार के बजाय जावा में गेम को फिर से लिखना) मूल रूप से मेरा MUD था जो 2005 में समाप्त हो गया था और मैं हाल ही में भाग गया हूं कि मैं अपनी बफ़र प्रणाली को कैसे लागू करना चाहता हूं? मैं इस प्रणाली का उपयोग करने जा रहा हूं क्योंकि इसने मेरे पिछले असफल खेल में अच्छी तरह से काम किया।
खैर, उम्मीद है कि किसी को, कहीं, इन अंतर्दृष्टि के कुछ उपयोगी मिल जाएगा।