"स्तर स्ट्रिंग" के लिए सबसे अच्छा समाधान?


10

मेरे पास एक गेम है जो स्तर की शुरुआत में एक यादृच्छिक स्तर का नक्शा बनाता है। मैं स्तर को बचाने और लोड करने के लिए कुछ तरीके लागू करना चाहता हूं।

मैं सोच रहा था कि सभी चर को बचाने के लिए XML एक अच्छा विकल्प होगा, फिर मेरे लिए कुछ ऐसा बनाना आसान होगा जो उस XML को पार्स कर सके और सटीक समान स्तर उत्पन्न कर सके।

लेकिन XML शायद मेरी जरूरतों के लिए ओवरकिल है। मुझे पुराने सेगा कंसोल के साथ दिन में वापस याद आया, जिसमें आपके गेम को बचाने की क्षमता नहीं थी (मुझे लगता है कि वर्म्स गेम ने भी ऐसा किया था), कि वे आपको चरित्र का एक गुच्छा देंगे जिसे आप लिख सकते हैं। यदि आप बाद में उस स्ट्रिंग में मुक्का मारते हैं, तो यह सटीक स्तर को लोड करेगा।

क्या "स्तर स्ट्रिंग" एक अच्छा विकल्प होगा? क्या यह किसी प्रकार का "आधार 60" रूपांतरण होगा? मैं इसे कैसे लागू करूंगा?

जवाबों:


20

संभवतः सभी को आपको बचाने की आवश्यकता है यादृच्छिक बीज, जो आमतौर पर सिर्फ एक इंट है। यदि आप इसे थोड़ा और अधिक अपारदर्शी बनाना चाहते हैं, तो आप बेस 64 में इंट को एनकोड कर सकते हैं, लेकिन संभवत: इसकी आवश्यकता नहीं है।


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

यह ठीक है, लेकिन अगर गेम खेला जा रहा है तो इसे डायनामिक डेटा भी स्टोर करना होगा। स्ट्रिंग को चरित्र पदों / स्कोर आदि को बचाने की आवश्यकता होगी ताकि इस स्ट्रिंग को उत्पन्न करने का सबसे अच्छा तरीका क्या हो?
एडम हर्ट जूल

मैं शायद JSON का उपयोग करूंगा (या XML अगर आप चाहें तो) विश्व स्थिति को क्रमबद्ध करने के लिए और फिर स्ट्रिंग को आधार-एनकोड करें। नहीं यकीन है कि सभी उपयोगी है, हालांकि, क्यों नहीं एक और अधिक जीयूआई उन्मुख / लोड प्रणाली को बचाने? मुझे लगता है कि यह वेब आधारित है और आप इस सर्वर पक्ष को संभालना नहीं चाहते हैं। शायद एक उदाहरण के लिए shygypsy.com/farm/p.cgi को देखें?
कोडरंगर

23

आपके सेव गेम्स के लिए आप जो भी फॉर्मेट इस्तेमाल करते हैं, नेकी के लिए एक वर्जन नंबर डालें। आप वर्जन नंबर पर ब्रांच करके बैकवर्ड-कंपेटिबल लोड कर पाएंगे, या आप बहुत पुराने हो चुके सेव्स को सुरक्षित रूप से पहचान पाएंगे। लोड करने के लिए।

यदि आप नहीं करते हैं तो आपको पछतावा होगा।


7
+1 वास्तव में प्रश्न का उत्तर नहीं देता है लेकिन इतना महत्वपूर्ण है।
जोनाथन फिशऑफ

10

JSON अच्छा है, लेकिन YAML बेहतर है। :) http://www.yaml.org/ और http://code.google.com/p/yaml-cpp/ में से किसी एक नेक-टू-यूज़ कार्यान्वयन के लिए।

YAML JSON का एक सुपरसेट है जो कुछ अच्छी विशेषताओं के लिए समर्थन जोड़ता है, विशेष रूप से:

  • बाइनरी नोड्स। यह उस प्रकार के डेटा को क्रमबद्ध करने के लिए बहुत अच्छा है जो आप स्तर के विवरण के लिए काम कर रहे हैं। JSON आपको अपनी पसंद के कुछ मध्यवर्ती प्रारूप में अनुवाद करने की आवश्यकता है, जैसे बेस 64, लिखने से पहले / पार्स करने के बाद। YAML में एक बाइनरी नोड प्रकार है जो पार्सर लाइब्रेरी को आपके लिए ऐसा करने के लिए कहता है।
  • इंट्रा-दस्तावेज़ संदर्भ। यदि दस्तावेज़ में एक ही वस्तु दो बार दिखाई देती है, तो JSON इसे दो बार लिखेगा, और जब आप इसे वापस पढ़ेंगे, तो आपको दो प्रतियां मिलेंगी। कई YAML उत्सर्जक इस स्थिति का पता लगा सकते हैं और दूसरी प्रति के बजाय, पहले संदर्भ का उत्पादन कर सकते हैं, जब लोड हो रहा हो तो पता लगाया जा सकता है।
  • कस्टम नोड प्रकार। आप प्रत्येक मानचित्र को उदाहरण के साथ किसी सूची में ध्वजांकित कर सकते हैं !! खिलाड़ी, !! शत्रु, आदि, और इसलिए अपनी प्रकार की जानकारी को अधिक से बाहर रखें।
  • YAML अधिक पठनीय स्वरूपण का समर्थन करता है।
  • चूंकि JSON YAML का सबसेट है, इसलिए अधिकांश YAML पाठकों को JSON दस्तावेज़ पढ़ने में कोई परेशानी नहीं होगी।

1
यमल बहुत शांत है, और यदि आप सुपरसेट की कुछ विशेषताओं से बचते हैं तो इसे बिना किसी कठिनाई के json में बदला जा सकता है।
जेथ्रो लार्सन

3

यदि आप गेम के सभी डेटा को क्रमबद्ध करना चाहते हैं, तो मैं JSON को आपके फ़ाइल प्रारूप के रूप में सुझाऊंगा, यही कारण है कि XML का उपयोग करना आसान है और कई भाषाओं में समर्थन बहुत अच्छा है।

मैंने इस लाइब्रेरी का उपयोग C ++ के लिए किया है और यह बहुत अच्छी तरह से काम करता है।

http://jsoncpp.sourceforge.net/


3

यदि आप आकार से सीमित नहीं हैं, तो XML एक अच्छा विकल्प है और यह मूल रूप से (जैसे .NET और फ्लैश में) समर्थित है, लेकिन यदि आप एक पतला प्रारूप चाहते हैं, तो आप अपना स्वयं का प्रारूप और पार्सर काफी आसान बना सकते हैं। मैं सामान्य रूप से 1 वर्ण का उपयोग करता हूं। प्रत्येक वस्तु को अलग करने के लिए अल्पविराम। स्ट्रिंग को डीकोड करने के लिए अल्पविराम पर एक विभाजन करें। अब प्रत्येक ऑब्जेक्ट को अलग-अलग गुणों की आवश्यकता होती है, इसलिए उन्हें एक अलग चरित्र जैसे कि सेमी कोलोन के साथ अलग करें, और प्रॉपर्टी वैल्स से संपत्ति के नामों को अलग करने के लिए किसी अन्य वर्ण का उपयोग करें, जैसे। बृहदान्त्र। इस प्रकार सभी को बिना स्ट्रिंग के आसानी से रीजेक्स के बिना आसानी से डिकोड किया जा सकता है। यहाँ एक उदाहरण है:

id:1;x:5;y:45.2;angle:45,id:28;x:56;y:89;angle:12;health:78

आप संपत्ति के नाम को 1 वर्ण से नीचे रखकर और भी अधिक स्थान बचा सकते हैं, जैसे स्वास्थ्य के लिए ज। उदाहरण के लिए।

i:1;x:5;y:45.2;a:45,i:28;x:56;y:89;a:12;h:78

JSON विकल्प की तुलना करें:

{"o":[{"i":1, "x":5, "y":45.2, "a":45}, {"i":28, "x":56, "y":89, "a":12, "h":78}]}

इसके अलावा, यदि आप अपने नंबरों का आकार कम करना चाहते हैं, तो आप मुद्रण योग्य UTF16 वर्णों के पूर्ण सेट का उपयोग करके उन्हें सांकेतिक शब्दों में बदलना कर सकते हैं। इस धागे ने मुझे स्टैक ओवरफ्लो पर एक सवाल पूछने के लिए प्रेरित किया कि आप एक ऑन-स्क्रीन चरित्र में कितना डेटा पैक कर सकते हैं । उत्तर पूर्णांक के लिए 40,000 से अधिक मानों पर लगता है, अगर आपको दिमाग, कांजी और शतरंज के टुकड़े होने का मन नहीं है: somewhere

एक और आकार में कमी प्राप्त करने के लिए, आप पढ़ सकते हैं / लिखने के आदेश का उपयोग यह निर्धारित करने के लिए कर सकते हैं कि कौन सा मूल्य है, इसलिए पहले दो वर्ण आईडी का प्रतिनिधित्व करते हैं, अगले दो x स्थिति हैं, अगले दो y, फिर कोण, फिर स्वास्थ्य , इत्यादि:

F5DGP@%&002DFTK#OP1F

अन्य उदाहरणों के समान सभी जानकारी संग्रहीत कर सकता है।

टाइल ग्रिड को एक स्ट्रिंग के रूप में संग्रहीत किया जा सकता है, जिसमें प्रत्येक पात्र एक अलग प्रकार की टाइल का प्रतिनिधित्व करता है जैसे:

i789pog5h3kl

जहां मेरा मतलब लावा, 9 मतलब घास आदि हो सकता है


यह मैं क्या पूछ रहा हूँ की तर्ज पर अधिक है। मैं अपने प्रश्न में XML का उल्लेख करता हूं, लेकिन फिर भी लोग इसका सुझाव देते हैं!
एडम हर्ट

1
उसके चारों ओर {} जोड़ें और आपके पास मूल रूप से JSON ;-)
कोडरंगर जूल

आपको उद्धरण चिह्नों का भार भी जोड़ना होगा। संभवतया वर्णों की संख्या दोगुनी होगी, लेकिन आपको वस्तुओं का घोंसला मिल जाएगा।
इयान

1

यदि आप .Net में कोडिंग कर रहे हैं तो XML के साथ जाना आसान है, जैसा कि आप अपने लेवल क्लास को एक्सएमएल में / एक्सपी के बाहर सिर्फ एक-दो लाइनों के साथ सीरियलाइज़ / डिस्क्रिअलाइज़ कर सकते हैं, और फिर एक अच्छी तरह से प्रबंधित क्लास में।

मानचित्र प्रकार का एक चर होगा जो आपके पास अपने सभी डेटा में लोड होता है।

Dim TheMap As New Map

मान लें कि आपके पास पहले से निर्मित एक मानचित्र वर्ग है, तो यह आपके मानचित्र को XML में बचाएगा:

Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))
Dim Strm As New FileStream("c:\Map.xml", FileMode.Create, FileAccess.Write, FileShare.None)
Serializer.Serialize(Strm, TheMap)
Strm.Close()

इसके बाद उस XML को आपके मानचित्र वर्ग में वापस लोड किया जाएगा, कोड में फिर से उपयोग किया जाएगा।

Dim Reader As New StreamReader("map.xml")
Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))

TheMap = Serializer.Deserialize(Reader)
Reader.Close()

इस बिंदु से आपकी XML फ़ाइल अब आसान उपयोग के लिए आपकी कक्षा में लोड हो गई है।

आपके "लेवल स्ट्रिंग" मुद्दे के लिए, जो पहले कहा गया था कि यह बहुत अच्छा काम करेगा, आप बस सीड नंबर को "लेवल स्ट्रिंग" के रूप में उपयोग कर सकते हैं।

अन्यथा, आप अभी भी कई अलग-अलग मानचित्रों को पहले से तैयार कर सकते थे जो आप चाहते थे, और उन सभी को "स्तर स्ट्रिंग" के साथ सहेजा गया है और फिर उचित नक्शे को खींचने के लिए इसका उपयोग करें।


+1 भले ही मैं एक्सएमएल से नफरत करता हूं - अगर भाषा एक डिफ़ॉल्ट क्रमांकन प्रारूप प्रदान करती है, तो पहले उस पर विचार करना सबसे अच्छा है, खासकर अगर यह एक प्रारूप है जो अन्य उपकरण सैद्धांतिक रूप से पार्स कर सकते हैं (जैसे XML / JSON / YAML)।

0

मैं structएक केंद्रीय स्थान पर सभी खेल राज्य को संग्रहीत करने के लिए एक सरल या समान डिवाइस (आपकी भाषा के आधार पर) का उपयोग करूंगा । यदि आप बसने / पाने वालों की सुरक्षा चाहते हैं, तो आप संरचना को एक में लपेट सकते हैं class

यदि आप इसे महसूस करते हैं, तो बिटफिल्ड का उपयोग करें या बस ऑपरेटरों का उपयोग करके अपने आप को थोड़ा हेरफेर करें।

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

आप पैडिंग को खत्म करते हुए #pragma(जैसे #pragma pack(1)) या __attribute__संरचना को बारीकी से पैक करने के लिए उपयोग करने में सक्षम हो सकते हैं । यह आपके कंपाइलर और टारगेट आर्किटेक्चर के आधार पर काम कर भी सकता है और नहीं भी।

ध्यान दें कि बिटफिल्ड और पैक प्रैग्मस या विशेषताओं का उपयोग पोर्टेबिलिटी को कम कर सकता है। हार्डवेयर आर्किटेक्चर के अलावा, स्ट्रक्चर फील्ड एंडियननेस (बाइट ऑर्डर) भी बदल सकता है। यदि आप पोर्टेबिलिटी के लिए प्रयास कर रहे हैं तो आप इससे बचना चाह सकते हैं।

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

एक बार आपकी संरचना हो जाने के बाद, इसे किसी xxencode फ़ंक्शन की तरह पास करें :

encode_save( char * outStringBuf, size_t outStringBufSize,
             const SaveStruct * inSaveData, size_t inSaveDataSize )

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

कभी structभी सही स्थानों पर पुराने स्कूल की शक्ति को कम मत समझो । हमने इसे GBA और DS गेम के लिए एक टन का उपयोग किया है।


कच्चा संरचना क्रमांकन गैर-पोर्टेबल और बेहद नाजुक wrt नया कोड है। जब तक यह बहुत सीमित संसाधनों के साथ एक मंच के लिए बेकिंग डेटा के अंतिम चरण के रूप में नहीं है, तब तक यह बहुत समयपूर्व अनुकूलन है। क्या कोई कारण है जिसे आप 6 बिट्स से 8 तक पसंद करते हैं? प्रारूप वैसे भी मानव-पठनीय नहीं है, आप वास्तविक संरचना लेआउट की गति और डीबगैबिलिटी का लाभ उठा सकते हैं।

@ जो: मैंने उल्लेख किया है कि यह गैर-पोर्टेबल है और कुछ संभावित चिंताएं हैं। प्रश्न विशेष रूप से पुराने सेगा खेल की तरह एक मानव-पठनीय "स्तरीय स्ट्रिंग" के लिए पूछा गया और बेस 60 रूपांतरण का उल्लेख किया गया; xxencode की तरह कुछ के माध्यम से एक संरचना गुजरती है। यह जरूरी नहीं कि एक समय से पहले का अनुकूलन हो: एक साधारण संरचना, बिटपैक नहीं है, डेटा को बचाने के लिए स्टोर करने का एक अच्छा "केंद्रीय" तरीका है, और बहुत से कोड को सरल कर सकता है जो डेटा के साथ इंटरैक्ट करता है। गैर-सदस्य गैर-मित्र संरचनाओं और "अंदर बाहर" प्रोग्रामिंग पर नोएल लोपिस के हाल के लेख देखें। यह सिर्फ KISS है।
leander

1
मैं इस तरह से पूरी तरह से सहमत हूं। हां, यह संस्करणों में पोर्टेबल नहीं है, न ही सिस्टम, लेकिन फिर से सेव-गेम्स वे संसाधन नहीं हैं जिन्हें विकास के दौरान पुन: उपयोग करने की आवश्यकता होती है, या प्लेटफार्मों के माध्यम से कॉपी की जाती है। डीबगिबिलिटी शायद ही कभी पढ़ने / लिखने में एक समस्या है, इसे एक बार लागू करें और यह हमेशा के लिए काम करेगा। यदि एक्स्टेंसिबिलिटी वास्तव में एक समस्या है - पहले ybyte / शब्द के रूप में एक संस्करण संख्या जोड़ें और आप उस पर स्विच कर सकते हैं (हालांकि यह डेटा भेद्यता को पेश करेगा)। ऐसा नहीं है कि xml संस्करण संबंधी समस्याओं को हल करने वाला है - केवल मान सेट करने की तुलना में अधिक शामिल होने की प्रवृत्ति। हां, मैं व्यावहारिक हूं।
काज

0

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

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