संभावित अनंत 2 डी मानचित्र डेटा स्टोर करने का एक तरीका?


29

मेरे पास एक 2 डी प्लेटफ़ॉर्मर है जो वर्तमान में 100 से 100 टाइलों के साथ विखंडू को संभाल सकता है, साथ ही चंक निर्देशांक लॉन्ग के रूप में संग्रहीत किए जाते हैं, इसलिए यह नक्शे की अधिकतम सीमा (अधिकतम * अधिकतम) है। सभी इकाई स्थिति आदि आदि प्रासंगिक हैं और इसलिए वहां कोई सीमा नहीं है।

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


2
कुछ डेटा संरचनाएं जिन्हें आप अधिक प्रेरणा के लिए देख सकते हैं वे विरल मैट्रेस और (मल्टीलेवल) पेज टेबल हैं
एंड्रयू रसेल

निम्न प्राथमिकता: क्या आप स्पष्ट कर सकते हैं कि "लंबी" डेटा प्रकार 32- या 64-बिट है?
Randolf रिचर्डसन

2
@ रैन्डोल्फ ने कहा कि यह C # है, संभवतः वह C # का अर्थ है longजो 64-बिट (इतना अधिकतम है Int64.MaxValue)।
एंड्रयू रसेल

नॉच के पास अपने ब्लॉग में Minecraft में अनंत नक्शों के बारे में कहने के लिए कुछ दिलचस्प बातें हैं: notch.tumblr.com/post/3746989361/terrain-generation-part-1
dlras2

जवाबों:


17

अपने गेम के लिए एक कस्टम मैप फॉर्मेट बनाएं। यह जितना आप सोच सकते हैं उससे कहीं ज्यादा आसान है। बस बाइनरीवेटर वर्ग का उपयोग करें। सबसे पहले हेडर को कुछ इन्ट्स या uints में लिखें। हेडर में शामिल करने के लिए जानकारी:

  • मैजिक स्ट्रिंग / मैजिक नंबर ऑफ यू फाइल फॉर्मेट।
  • इस फ़ाइल में वर्णित विखंडू का प्रारंभ / अंत / आकार

और भी (और यहाँ प्रदर्शन महत्वपूर्ण हिस्सा आता है

  • इनट्स जो फ़ाइल के अंदर शुरुआती स्थिति का वर्णन करते हैं। तो आप विशिष्ट हिस्सा खोजने के लिए नहीं है।

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

फिर, जब आप एक विशिष्ट चंक लोड करना चाहते हैं, तो आपको बस सूचकांक के अंदर खोजना होगा। जब आपको पोजिशन मिली तो बस fileStream.Position = PositionOfChunkFromIndex सेट करें और आप इसे लोड कर सकते हैं।

यह सभी फ़ाइलफ़ॉर्मेट के डिज़ाइन के बारे में है जिसमें हेडर के साथ फ़ाइल की सामग्री का सबसे कुशलता से वर्णन किया गया है।

बस आपके द्वारा बनाए गए कस्टम एक्सटेंशन के साथ फ़ाइलों को सहेजें और आप वहां जाएं।

बोनस: फ़ाइल / विशिष्ट सामग्री (हेडर नहीं !!) के विशिष्ट क्षेत्रों के लिए BZip2 संपीड़न जोड़ें, ताकि आप फ़ाइल से विशिष्ट विखंडू को बहुत छोटे मेमोरी फ़ुटप्रिंट के लिए अनपैक कर सकें।


12
यह इंगित करने योग्य है कि, यदि आप इस फाइल को ऑन-द-फ्लाई में संशोधित करने जा रहे हैं, तो आप एक निश्चित आकार या बाहरी हेडर / इंडेक्स चाहते हैं, जैसे कि आप फाइल को फिर से लिखने के बिना चंक्स जोड़ सकते हैं। संपूर्ण फ़ाइल (ऑफ़सेट्स बदलने के कारण)।
एंड्रयू रसेल

उस बिंदु पर, क्या आप सिर्फ एक फ्लैटफाइल डेटाबेस को लागू नहीं कर रहे हैं?
एपे-इनोगो

13

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

आप प्रत्येक नोड के लिए एक न्यूनतम परिमाण निर्दिष्ट कर सकते हैं (7 की परिमाण 128x128 होगा) और एक बार किसी भी नोड के पास इसके सबऑनोड्स का निर्दिष्ट प्रतिशत होता है, यह स्वतः ही दो आयामी सरणी में समतल कर देता है। इसका मतलब है कि बहुत घनी आबादी वाला हिस्सा (जैसे, पूरी तरह से पता लगाया गया महाद्वीप) एक सरणी (बहुत तेज़) का प्रदर्शन होगा, लेकिन एक कम आबादी वाला हिस्सा (उदाहरण के लिए, एक किनारे पर कोई व्यक्ति ऊपर और नीचे घूमता है लेकिन अंतर्देशीय नहीं देखा होगा) अच्छा प्रदर्शन और कम मेमोरी का उपयोग करें।

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

मैंने अभी तक किसी फ़ाइल में डेटा संग्रहीत करने के लिए इसका उपयोग नहीं किया है, लेकिन यह एक दिलचस्प समस्या है और मैं इससे निपट सकता हूं।


तो यह मूल रूप से एक विस्तार योग्य पेड़ है, है ना? मुझे किसकी याद आ रही है?
काओड

2
एक विस्तार योग्य पेड़ पर सबसे बड़ा सुधार यह है कि यह पेड़ के कुछ नोड्स को 'समतल' करता है जो पेड़ों की तरह संरचित रखने के बजाय 2 डी सरणियों में भारी आबादी (डिफ़ॉल्ट 70%) हैं। यह आपको अनंत व्यूह के (अनंत) आकार के बिना एक सरणी लुकअप की गति प्रदान करता है।
dlras2

दोनों पत्ती और आंतरिक नोड्स, है ना? दिलचस्प विचार, अच्छे परिणाम दे सकता है, अगर मुझे कभी इसकी आवश्यकता होगी तो मैं इसे आजमाऊंगा। कोड और त्वरित उत्तर देने के लिए Btw, +1! ओह, और यूनिट परीक्षण भी किया है, मैं (दुख की बात है) कभी भी अपने व्यक्तिगत परियोजनाओं में ऐसा नहीं करते :)
kaoD

हम अपने काम पर कोई इकाई परीक्षण नहीं करते हैं, इसलिए दुख की बात है कि यह मेरे विद्रोह का तरीका है। मैंने इसके लिए एक डेमो ऐप बनाया, जो दिखाता है कि यह कैसे पॉपुलेट करता है और सपाट होता है, इसलिए यदि मैं अगले कुछ दिनों में इसे साफ कर सकता हूं दिन तो यह प्रस्तुत करने योग्य है, मैं इसे यहाँ भी पोस्ट करूँगा। यह बहुत अधिक समझ में आता है जब आप इसे देखते हैं।
dlras2

1
मैं इसे खो दिया है, माफ करना! मैं अभी भी इसे साफ करवाना चाहता हूं, लेकिन मैं धीरे-धीरे क्लास और होमवर्क के बीच के कुछ कोड को फिर से तैयार कर रहा हूं, ताकि कुछ समय के लिए ऐसा न हो। अभी के लिए, पुराना, संयुक्त राष्ट्र-सुंदर डेमो यहां है: j.mp/qIwKYt संयुक्त राष्ट्र-सुंदर से, मेरा आंशिक रूप से मतलब है कि इसे बहुत स्पष्टीकरण की आवश्यकता है, इसलिए README को पढ़ना न भूलें और यहां प्रश्न पूछने के लिए स्वतंत्र महसूस करें या ईमेल के माध्यम से।
dlras2 23

3

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

  PostgreSQL (स्वतंत्र और खुला स्रोत)
  http://www.postgresql.org/

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

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

मैंने देखा है कि कुछ गेम पहली बार प्राप्त करने के बाद स्थानीय हार्ड ड्राइव पर मैप डेटा का एक "कैश" रखते हैं (यह निस्संदेह नेटवर्क I / O को कम करने के लिए है), जैसे कि एशेन साम्राज्य:

  एशेन साम्राज्य (खेलने के लिए स्वतंत्र, सुंदर 2 डी कार्यान्वयन)
  http://www.ashenempires.com/

प्रत्येक चंक / टाइल के साथ "अंतिम अपडेटेड" टाइमस्टैम्प्स पर नज़र रखना भी मददगार होगा, जहाँ से स्थानीय रूप से संग्रहीत डेटा उपलब्ध है, SQL क्वेरी में अतिरिक्त "WHERE टाइमस्टैम्प_कॉल्यूम> $ local_timestamp" क्लैस शामिल हो सकता है ताकि केवल अपडेट किए गए चंक्स / टाइलें मिलें डाउनलोड (इस तरह बैंडविड्थ को बचाने के दो लाभ कम कनेक्टिविटी लागत, और आपके खिलाड़ियों के लिए कम अंतराल है, जो तब और अधिक स्पष्ट हो जाएगा जब आपका गेम लोकप्रिय होगा)।

एशेन एम्पायर्स का एक स्क्रीन शॉट (कुछ पात्र एक स्थानीय बैंक में हैं, और फर्श पर उन हड्डियों की बनावट से ऐसा लगता है कि कुछ कंकाल राक्षसों में भटक गए होंगे और स्थानीय शहर के गार्ड द्वारा हत्या कर दी गई थी:

enter image description here


2

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

सैद्धांतिक रूप से आप शाब्दिक रूप से अनंत मानचित्र बना सकते हैं जो इस तरह एक बहुत छोटी फ़ाइल को बचाएगा।


@ जोश पेट्री मेरी पोस्ट के लिए महत्वपूर्ण और महान भाषा / शैलीगत सुधार के लिए धन्यवाद। अफ़सोस कि मैं संपादित नहीं कर सकता: -D
sh कोड

1

क्या कोई तरीका है जिससे आप विखंडन कर सकते हैं (कुछ प्रकार के 'उपमहाद्वीप / देश' आप में हैं)? तो हो सकता है कि आपके पास किसी तरह की इंडेक्स फाइल हो जो आपको जल्दी से पता लगा सके कि कौन सी सब-फाइल / बड़ी फाइल का हिस्सा है जिसे आपको मेमोरी में चंक करने के लिए लोड करना है ...


वहाँ हमेशा एक तरह से आप हिस्सा विभाजन कर सकते हैं। हमेशा। वे खिलाड़ी के लिए दिखाई दे रहे हैं / बाकी प्रणाली के लिए प्रासंगिक है या नहीं, हमेशा दुनिया डेटा को विखंडू में विभाजित करने का एक तरीका है, आमतौर पर कई अलग-अलग तरीकों से।
sh कोड

0

आप Minecraft से विचार ले सकते हैं। मूल रूप से उनके पास प्रति चंक एक फ़ाइल थी। अब वे MCRegion प्रारूप का उपयोग करते हैं, जो 32x32 क्षेत्रों में समूह बनाता है और प्रति फ़ाइल उन में से एक को संग्रहीत करता है।

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