ड्यूटी पर, आकस्मिक गेम (अधिकांश भाग के लिए, quests) के लिए क्रॉस-प्लेटफ़ॉर्म इंजन को लागू करने की आवश्यकता थी। इस लेख में मैं कुछ गैर-तुच्छ मुद्दों के बारे में बात करने की कोशिश करूंगा जो हमने विकास के दौरान तय किए थे।
परिचय
इंजन को कम से कम तीन प्लेटफार्मों का समर्थन करना चाहिए: पीसी, मैकओएस एक्स और आईओएस। इसका उपयोग quests बनाने के लिए किया जाता है, इसलिए दृश्य सौंदर्य पर अधिक जोर दिया जाता है: कण प्रणाली, एनिमेशन और वीडियो।
इंजन निम्नलिखित संस्थाओं पर आधारित है:
- मुख्य इंजन वर्ग, जो विंडो बनाने में जिम्मेदार है, उपयोगकर्ता इनपुट, फोकस / हानि, इंजन के अन्य सभी भागों का नियंत्रण;
- रेंडरिंग क्लास;
- संसाधन प्रबंधक - लोडिंग, भंडारण, अनलोडिंग संसाधन (बनावट, फोंट)।
ये तीन बड़ी इकाइयाँ स्वयं पूरी तरह से आत्मनिर्भर हैं और इंजन के बाकी हिस्सों पर कोई बाहरी निर्भरता नहीं है, इसलिए जब हमने iOS के लिए आर्केड बनाया, तो हमने बस उन्हें लिया और शीर्ष पर एक्शन रैपर लपेटा।
आधार के ऊपर, खेल (खोज) भाग सीधे बनाया गया था। इसके निर्माण में मुख्य विचार खेल संस्थाओं के नियंत्रण, निर्माण और लोडिंग की एकरूपता थी।
यह एक परिचय था, अब सब कुछ के बारे में अधिक विस्तार से।
क्रॉस-प्लेटफॉर्म कार्यान्वयन
यह हमारी मुख्य चिंता थी। हर साल 10 खेलों को बनाना और इस सभी अपमान की दस भाषाओं के लिए बहुत सारे स्थानीयकरण खर्च करना, हम प्रत्येक खेल के इस अलग पोर्टिंग को जोड़ने का जोखिम नहीं उठा सकते थे। अलग क्यों? क्योंकि हमारी कंपनी को तीन शहरों में वितरित किए गए 5 कार्य समूहों में विभाजित किया गया था, और प्रत्येक समूह के पास अपना स्वयं का प्रोग्रामर था, जिसने अपनी बाइक को चुना। काम का अनुकूलन करने के लिए, हमने सभी मौजूदा खेलों को सामान्य इंजन और उपकरणों के विचार के लिए लोगों की नैतिक तैयारी के लिए उपलब्ध इंजनों में से सर्वश्रेष्ठ में स्थानांतरित कर दिया, एक प्रोग्रामर को निकाल दिया गया, और बाकी को वर्तमान परियोजनाओं के बीच आवंटित किया गया और उन्हें एक नए आम इंजन पर काम करने के लिए समय आवंटित किया गया।
पोर्टिंग को सरल बनाने के लिए, हमने सभी प्लेटफ़ॉर्म-विशिष्ट कोड को यथासंभव कुछ वर्गों में स्थानीय बनाने का प्रयास किया, और सभी प्लेटफ़ॉर्म के लिए कोड के साथ मुख्य कार्य का संचालन किया। परिणामस्वरूप, हम प्लेटफ़ॉर्म-डिपेंडेंट क्लास बन गए हैं: टेक्सचर, रेंडरिंग क्लास, विंडो मैनेजर, फाइल सिस्टम एक्सेस और साउंड। उपयोग किए गए प्लेटफ़ॉर्म के बारे में बाकी कोड नहीं जानने के लिए, हमने कारखाने में निम्न-स्तरीय वस्तुओं का निर्माण किया, जिसने नियंत्रण निर्देशों के आधार पर वांछित वस्तु बनाई। निम्न-स्तरीय वस्तुओं को सीधे (नया) बनाना निषिद्ध था।
पीसी और मैकओएस एक्स का कार्यान्वयन प्लेग्राउंड लाइब्रेरी का उपयोग करके किया गया था, क्योंकि हम इस लाइब्रेरी के साथ लंबे समय से काम कर रहे हैं और यह सुनिश्चित कर सकते हैं कि हमें एक गेम मिलेगा जो बहुत बड़ी संख्या में उपयोगकर्ताओं के लिए काम करता है। IOS के लिए, हमने खुद को OpenGL ES पर सब कुछ लागू किया। हमें बनावट में प्रतिपादन और बनावट में मनमाना पिक्सेल तक पहुंच के अलावा कोई कठिनाई नहीं थी।
खेल संस्थाओं की संरचना करना
मैंने सैंडबॉक्स में इस एक पोस्ट के बारे में पहले ही लिखा था, लेकिन जाहिर है कि यह बहुत नहीं था।
यह विचार है कि सभी गेम इकाइयाँ एक सामान्य प्रणाली में हैं और एक सामान्य इंटरफ़ेस है। किसी भी खेल को इंजन और खेल में ही विभाजित किया जा सकता है। तो खेल ही और इसके अंदर किसी भी संस्था को इंजन में परिभाषित ऑब्जेक्ट के एक सामान्य वर्ग से विरासत में मिला है और सभी बुनियादी कार्यों को लागू करना है: प्रक्रिया, इनपुट, रेंडरिंग, लोडिंग, अनलोडिंग, बच्चों का प्रबंधन। प्रत्येक ऑब्जेक्ट का एक अनूठा नाम होता है जो स्तर डिजाइनरों द्वारा उत्पन्न या सेट किया जाता है। एक सामान्य इंटरफ़ेस होने पर, कोई भी प्रोग्रामर किसी भी कोड को सही कर सकता है, क्योंकि हर जगह सब कुछ समान है। पहले से ही तीन गेम पूरे करने के बाद, हमने गेम कोड का विश्लेषण किया और देखा कि गेम ऑब्जेक्ट्स के लिए अद्वितीय विधियों की संख्या जो बेस ऑब्जेक्ट में कार्यान्वित नहीं की जाती है, प्रति वर्ग एक या दो से अधिक नहीं है। मैं कल्पना नहीं कर सकता कि हम इस चिड़ियाघर के साथ कैसे रहते थे और उनके अंदर के तरीके।
इस विचार का दूसरा पक्ष एक पेड़ की संरचना बनाना था। प्रत्येक ऑब्जेक्ट किसी का है, किसी ने इसे बनाया है, और कोई इसे हटा देगा। सभी वस्तुएं एक दूसरे से जुड़ी हुई हैं। इस पदानुक्रम के शीर्ष पर दो ऑब्जेक्ट हैं: "रूट" और "वॉल्ट"। सब कुछ जो जड़ से जुड़ा हुआ है, खींचा जाता है, संसाधित किया जाता है, इनपुट करता है; सब कुछ जो जड़ से चिपक जाता है वह स्वचालित रूप से अपने संसाधनों को लोड करता है; जो इससे अलग है वह संसाधनों को अनलोड करता है। "रिपॉजिटरी" बस अपने अंदर कुछ ऐसा संग्रहित करता है जिसकी अभी आवश्यकता नहीं है, लेकिन यह काम में आ सकता है और डाउनलोड करने का समय नहीं होगा; "रिपॉजिटरी" में संग्रहित आइटम भी हैं जिनकी स्थिति को याद किया जाना चाहिए और उपयोगकर्ता को बाद में उसी रूप में दिखाया जाना चाहिए। यही है, इन दो सुपर-ऑब्जेक्ट्स के बीच वस्तुओं को खींचकर, हम स्क्रीन पर प्रदर्शित की जाने वाली चीजों को नियंत्रित करते हैं। किसी भी वस्तु तक पहुंच इसके अनूठे नाम द्वारा एक पुनरावर्ती खोज प्रक्रिया के लिए किया जाता है।
आप एक ऑब्जेक्ट बना सकते हैं और इसे कहीं भी संलग्न नहीं कर सकते हैं, लेकिन, सबसे पहले, यह ऑब्जेक्ट कभी भी खींचा या एनिमेटेड नहीं होगा, जिसे तुरंत उस व्यक्ति द्वारा देखा जाएगा जिसने इसे बनाया है, और दूसरी बात, यह खोज प्रक्रियाओं का उपयोग करके नहीं पाया जा सकता है , जिस पर तुरंत गौर किया जाएगा और उसे खत्म कर दिया जाएगा।
खेल संपादक
हम C # में एडिटर लिख रहे हैं। यह सुविधाजनक है, तेज और स्तरीय डिजाइनर मानक विंडोज इंटरफ़ेस और हॉटकीज़ से खुश हैं। और हम C ++ में गेम लिखते हैं। और यहाँ समस्याएँ उत्पन्न होने लगती हैं ...
स्तरीय डिजाइनरों का सपना खेल के साथ संयुक्त एक संपादक है, वह है: एक खेल खेलना - एक बग ढूंढें - संपादक मोड पर स्विच करें - एक बग को ठीक करें - खेल मोड पर स्विच करें - आगे खेलें। यही है, संपादक की आवश्यकताएं इस प्रकार थीं: एक तरफ, खेल एक ही समय में एक संपादक होना चाहिए, दूसरी तरफ, संपादक के पास मानक खिड़कियां, नियंत्रण और प्रबंधन सिद्धांत होने चाहिए।
सबसे पहले, हमने ओपनजीएल और डायरेक्टएक्स के लिए विभिन्न नियंत्रण पुस्तकालयों के बारे में सोचा था, लेकिन डिजाइनरों ने यह कहना शुरू कर दिया कि वे क्या पसंद करते हैं और क्या नहीं। हम उनसे मिलने गए - वे अब भी पांच गुना अधिक हैं, जहां प्रोग्रामर हैं।
तब एक विचार का जन्म हुआ, जो कई परिवर्तनों से गुजरा, जिसके परिणामस्वरूप अब हमारे पास है। विवरण के साथ आपको परेशान न करने के लिए, मैं तुरंत आपको अंतिम संस्करण बताऊंगा।
लब्बोलुआब यह है कि खेल में वास्तव में एक संपादक शामिल है, अर्थात, संपूर्ण नियंत्रण कोड खेल में है, इंजन में अधिक सटीक है, और संपादक सिर्फ एक सुंदर नियंत्रण खोल है जिसके साथ आप इस कोड को नियंत्रित कर सकते हैं। खेल और संपादक की शुरुआत में, वे एक-दूसरे के साथ प्रारंभिक डेटा का आदान-प्रदान करते हैं, और फिर किसी भी समय संपादक में एक बटन दबाकर, खेल संपादन मोड में प्रवेश करता है, डिजाइनर को सभी कार्यक्षमता प्रदान करता है। संपादक विंडो लोड किए गए मॉड्यूल और अन्य सेवा जानकारी प्रदर्शित करती है। उसी समय, संपादक अपने आप में कुछ भी संग्रहीत नहीं करता है, यह केवल आदेश भेजता है और उत्तर प्राप्त करता है। यह संपादक और खेल में जानकारी के दोहराव से बचने के लिए किया गया था, और दोनों स्थानों पर डेटा अपडेट करने के साथ बड़े बवासीर। इस समाधान में प्रासंगिक डेटा प्राप्त करने के लिए कुछ स्थानों पर कुछ अतिरिक्त क्लिकों की एक खामी है, लेकिन हमने इसे अभी के लिए सहन करने का फैसला किया है।
WM_COPYDATA संदेशों का उपयोग करके गेम और संपादक के बीच डेटा का आदान-प्रदान किया जाता है, जो आपको अनुप्रयोगों के बीच डेटा भेजने की अनुमति देता है। डेटा XML में पैक किया गया है। यह भविष्य के परिवर्तनों को सरल बनाने के लिए किया जाता है।
निष्कर्ष
ये मुख्य बिंदु थे जिन्होंने हमें एक सरल और पोर्टेबल गेम इंजन को लागू करने की अनुमति दी। कई और विवरण थे जो एक अलग लेख में जारी किए जाएंगे।