खेल संसाधनों के लिए एक उदाहरण या एक वर्ग का उपयोग करें (लकड़ी, लोहा, सोना)


31

इसलिए मैं एक खेल बना रहा हूं, जहां आप लकड़ी, लोहा, सोना, आदि जैसे संसाधनों को बेचने या खरीदने के लिए स्थानों को भेज सकते हैं।

अब मैं सोच रहा था कि डे गेम में संसाधन कैसे बनाए जाएं। मैं 2 विकल्प लेकर आया हूं

  1. प्रत्येक संसाधन के लिए एक क्लास बनाएँ:

    public class ResourceBase {
        private int value;
        // other base properties
    }
    
    public class Gold : ResourceBase {
         public Gold {
             this.value = 40 // or whatever
         }
    }
  2. एक संसाधन वर्ग के उदाहरण बनाएँ

    public class Resource {
        string name;
        int value;
    
        public Resource(string name, int value) {
            this.name = name;
            this.value = value;
         }
     }
    
    // later on...
    
    Resource gold = new Resource("Gold",40);

दूसरे विकल्प के साथ गेम रिसोर्सेस को रिसोर्स से भरना संभव है। जसन फाइल, मैं उस स्ट्रक्चर को पसंद करता हूं।

नए विचारों / डिजाइन पैटर्न / संरचनाओं का हमेशा स्वागत है!

EDIT: यह हत्यारों पंथ ब्लैक फ्लैग के साथी ऐप की तरह थोड़ा सा है। नीचे दी गई छवि पर संसाधन पट्टी देखें

संपादित 2: मैंने "JSON फ़ाइल से आइटम / संसाधन लोड" पर कुछ और शोध किया है और इस ब्लॉग को पाया: खेल विकास में JSON की शक्ति - आइटम । यह विकल्प 1 और विकल्प 2 का सबसे अच्छा दिखाता है। आप अभी भी प्रत्येक संसाधन में कार्यक्षमता जोड़ने में सक्षम हैं :)

यहाँ छवि विवरण दर्ज करें


1
Minecraft में प्रत्येक संसाधन के लिए अलग-अलग कक्षाएं हैं (यह नहीं कि आपको चाहिए)
MCMastery

@MCMastery ओह्ह मिनीक्राफ्ट ओपन-सोर्स है? मैं उस संरचना पर एक नज़र डालना चाहूंगा। और उल्लेख के लिए thx
MDijkstra

1
यह नहीं है, लेकिन यह हमेशा सर्वरों के लिए de-obfuscated किया जा रहा है ... github.com/Wolf-in-a-bukkit/Craftbukkit/tree/master/src/main/…
MCMeryery

12
इस तरह एक स्ट्रिंग का उपयोग न करें। यह "ग्लोड" या समान के साथ "गोल्ड" को गलत तरीके से समझने के लिए बहुत आसान है, और यह डिबग करने के लिए बहुत बड़ा दर्द है। enumइसके बजाय उपयोग करें ।
नोलोनार

Minecraft तकनीकी रूप से खुला स्रोत नहीं है, लेकिन यह लगभग पूरी तरह से विघटित हो गया है और नष्ट हो गया है। आपको इंटरनेट पर कहीं भी एक विकृत स्रोत खोजने में सक्षम नहीं होना चाहिए, लेकिन आप इसे files.minecraftforge.net (MDK डाउनलोड वही है जिसे आप चाहते हैं) से करने के लिए प्रक्रिया को डाउनलोड और चला सकते हैं
JamEngulfer 415 1516

जवाबों:


51

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


संपादित करें:

यह सामान्य अच्छे व्यवहार में क्यों है, इस पर थोड़ा और विस्तार करने के लिए, भले ही आप 100% सुनिश्चित हों कि कुछ मूल्य कभी भी नहीं बदलेंगे।

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

कंसोल पर एक गेम जारी करते समय, इन्हें आमतौर पर एक समीक्षा प्रक्रिया से गुजरना पड़ता है, जहां कंसोल निर्माता की अपनी क्यूए गेम का परीक्षण करेगी, इसके माध्यम से खेलेगी, मुद्दों की तलाश करेगी, आदि यह अनिवार्य है और पैसा खर्च करता है, बहुत सारा पैसा। मुझे लगता है कि मैंने एक बार पढ़ा है कि एक रिलीज में केवल प्रमाणन के लिए 30,000-50,000 डॉलर खर्च हो सकते हैं।

अब कल्पना कीजिए कि आप अपने गेम को रिलीज़ के लिए धक्का दे रहे हैं, 30,000 डॉलर का भुगतान करें और प्रतीक्षा करें। और अचानक आप नोटिस करते हैं कि आपके कुछ खेल मूल्य सचमुच टूट गए हैं। मान लीजिए कि आप 50 सोने के लिए लोहे की सलाखों को खरीद सकते हैं और उन्हें 55 सोने के लिए बेच सकते हैं।

आप क्या करते हैं? यदि आपने उस सामान को हार्ड-कोडित किया है, तो आपको एक नया अपडेट / रिलीज़ संस्करण बनाना होगा, जिसे एक बार फिर से समीक्षा से गुजरना होगा, इसलिए सबसे खराब स्थिति में आप एक बार फिर से प्रमाणीकरण के लिए भुगतान करेंगे! मुझे यकीन है कि Ubisoft बुरा नहीं होगा, लेकिन अपने छोटे इंडी खेल डेवलपर जेब के लिए ... ouch!

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

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


6
DDD के लिए +1। यह संसाधनों के रूप में ऐसी चीजों के लिए बहुत उपयुक्त है।
क्रॉम्स्टर का कहना है कि

@Funnydutchman यदि किसी के उत्तर ने आपकी मदद की है, तो यह स्टैक एक्सचेंज पर प्रथागत है, संख्या के ऊपर तीर को क्लिक करके उनके उत्तर को छोड़ दें। यदि किसी उत्तर ने आपको सबसे अधिक मदद की है, तो आपको उनके उत्तर को स्वीकार करने के लिए नीचे तीर के नीचे दिए गए चेकमार्क पर क्लिक करना चाहिए। दोनों कार्रवाई उत्तरदाता को प्रतिष्ठा में एक बोनस देती है और समुदाय के लिए जवाब देने योग्य उत्तर अधिक दिखाई देती है।
नजल्ल

2
मैं नहीं देखता कि आपको पहले तरीके से कोड को कैसे लिखना होगा; आप सभी एक वर्ग जोड़ सकते हैं (जब तक कि मैं कुछ याद नहीं कर रहा हूँ)।
सरप्यथन

4
और यहाँ ऑब्जेक्ट ओरिएंटेड कोड और ऑब्जेक्ट ऑब्सेस्ड कोड के बीच अंतर है। सिर्फ इसलिए कि आप एक वस्तु बना सकते हैं पदानुक्रम जरूरी नहीं है कि आपको इसका मतलब होना चाहिए।
corsiKa

2
@ AgustínLado यदि मेरे पास हर बार एक ग्राहक के लिए एक डॉलर होता है, तो "यह कभी नहीं बदलेगा" और यह बदल गया, मैं हम दोनों को एक अच्छे रेस्तरां में रात के खाने के लिए ले जा सकता था (हालांकि हमें टिप पर थोड़ा कंजूसी करनी होगी, इसलिए शायद केवल एक औसत दर्जे का रेस्तरां ... अभी भी दो के लिए रात के खाने के लिए पर्याप्त समय है।)
corsiKa

29

अंगूठे का एक नियम यह है कि आप विभिन्न वर्गों का उपयोग करते हैं जब वस्तुओं को अलग-अलग कोड और एक ही वर्ग के उदाहरणों की आवश्यकता होती है जब ऑब्जेक्ट्स को केवल अलग-अलग मानों की आवश्यकता होती है।

जब संसाधनों में अलग-अलग गेम मैकेनिक होते हैं जो उनके लिए अद्वितीय होते हैं, तो यह कक्षाओं के साथ उनका प्रतिनिधित्व करने के लिए समझ में आता है। उदाहरण के लिए, जब आपके पास प्लूटोनियम होता है, जिसमें आधा-जीवन का समय होता है और खरगोश जो रिट्रेसमेंट अनुक्रम के अनुसार खरीदता है , तो इसका मतलब यह हो सकता है कि बेस-क्लास Resourceएक विधि के Updateरूप में लागू किया जाए, जो कि नो-ऑप और दो व्युत्पन्न वर्गों के रूप में कार्यान्वित होता है HalfLifeResourceऔर SelfGrowingResourceजो मान को कम करने / बढ़ाने के लिए उस विधि को ओवरराइड करें (और शायद यह भी शामिल करें कि शासन को तब लागू करें जब आप दोनों एक दूसरे के बगल में स्टोर करें)।

लेकिन जब आपके संसाधन वास्तव में केवल गूंगे नंबर होते हैं, तो यह उन्हें एक साधारण चर की तुलना में अधिक फैंसी कुछ भी लागू करने के लिए कोई मतलब नहीं है।


धन्यवाद @Phillipp आपके उत्तर के लिए। मेरे द्वारा यही विचार किया जा रहा था। लेकिन संसाधन वास्तव में संपत्तियों / विधियों के संदर्भ में नहीं बदलेंगे, इसलिए मैं अभी के लिए विकल्प 2 के साथ
जाऊंगा

14

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

interface IHasResources {
  int Gold { get; set; }
  int Wood { get; set; }
  int Cloth { get; set; }
  // ....
}

class Player : IHasResources { }
class City: IHasResources { }

इसके अलावा, इसका उल्टा यह है कि आप एक शहर को ठीक उसी कोड के साथ लूट सकते हैं जैसे आप दुश्मन के बेड़े को लूटेंगे, कोड के पुन: उपयोग को बढ़ावा देंगे।
नकारात्मक पक्ष यह है कि इस तरह के इंटरफ़ेस को लागू करना थकाऊ साबित हो सकता है यदि कई वर्ग इसे लागू करते हैं, तो आप अंतरापृष्ठों का उपयोग कर सकते हैं, लेकिन मूल समस्या के लिए नहीं, इसे विकल्प 1 या 2 के साथ हल कर सकते हैं:

interface IHasResources { 
   IEnumerable<Resource> Resources { get; }
}

उदाहरण (एनम के साथ): कुछ मामलों में, संसाधन प्रकार को परिभाषित करते समय स्ट्रिंग के बजाय एनम का उपयोग करना वांछनीय होगा:

enum Resource {
   Gold, Wood, Cloth, //...
}

class ResourceStorage {
   public Resource ResourceType { get; set; }
   public int Value { get; set; }
}

यह "सुरक्षा" का एक सा प्रदान करेगा, क्योंकि आपका आईडीई आपको डॉट लिखने के बाद इसे असाइन करते समय सभी वैध संसाधनों की सूची देगा ResourceType = Resource., इसके अलावा आपके द्वारा आवश्यक श्लोकों के साथ और भी "ट्रिक्स" हैं , जैसे स्पष्ट प्रकार या रचना / झंडे जिसे मैं क्राफ्ट करते समय उपयोगी होने की कल्पना कर सकता हूं:

[Flags]
enum Metal {
 Copper = 0x01/*01*/, Tin = 0x02/*10*/, Bronze = 0x03/*11*/
}
Metal alloy = Metal.Copper; //lets forget Value(s) for sake of simplicity
alloy |= Metal.Tin; //now add a bit of tin
Console.WriteLine(alloy); //will print "Bronze"


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


2
आपके उत्तर के लिए धन्यवाद @wondra मुझे एनम विकल्प पसंद है और आपने तांबे और टिन से बाहर कांस्य कैसे बनाया
एमडीजिक्स्ट्रा

2
मैं इस समुदाय में विशेष रूप से शामिल हुआ, ताकि मैं एनम समाधान को वोट कर सकूं। आप enum का उपयोग करने में भी देख सकते हैं कि Enum के कुछ JSON प्रतिनिधित्व ( my-great-enum) से कुछ C # प्रतिनिधित्व करने वाले Enum ( ) के मानचित्र का वर्णन करने की विशेषता है MyGreatEnum
डैन फोर्ब्स

जाहिरा तौर पर मैं जावा-लूप से बहुत लंबे समय से बाहर हूं। कब से यह इंटरफेस के लिए क्षेत्र की घोषणा करने की अनुमति है? जहां तक ​​मुझे पता है कि वे स्वचालित रूप से स्थिर और अंतिम हैं, और इस प्रकार प्रश्न में वर्णित उद्देश्यों के लिए बहुत अधिक उपयोग नहीं किया गया है।
एम। हर्जकम्प

2
@ M.Herzkamp यह एक क्षेत्र नहीं है, यह एक संपत्ति है - और जावा गुणों का समर्थन नहीं करता है। प्रश्न को C # टैग किया गया है, C # इंटरफेस में गुणों की अनुमति दें - गुण सब के बाद के तरीके हैं। मुझे डर है कि झंडे के एनोटेशन के लिए वही जाता है, जावा में समर्थित नहीं है, हालांकि मुझे पूरी तरह से यकीन नहीं है।
वंद्रा

इसे साफ करने के लिए धन्यवाद! मैं C # टैग से चूक गया और प्रश्न में कोड बहुत ही समान रूप से देखा गया जावा: D
M.Herzkamp

2

आपको विकल्प 1 का उपयोग करना चाहिए, जिसमें 3 फायदे हैं:

  1. संसाधन को त्वरित करना आसान है - एक पैरामीटर के रूप में संसाधन के प्रकार को पारित करने के बजाय, आप उदाहरण के लिए, बस करेंगे। new Gold(50)
  2. यदि आपको किसी संसाधन को विशेष व्यवहार देने की आवश्यकता है, तो आप इसे बदलकर कक्षा कर सकते हैं।
  3. यह जांचना आसान है कि क्या संसाधन एक निश्चित प्रकार है - resource instanceof Gold

सभी उत्तरों में उनके पेशेवरों और विपक्ष हैं, यह चुनना मुश्किल है कि कौन सा बेहतर है। मैंने इस सवाल का संपादन किया है, आप उस संरचना के बारे में क्या सोचते हैं?
MDijkstra

1

यदि आपके संसाधनों का अपना कोई व्यावसायिक तर्क नहीं है, या विशेष मामला परिदृश्य के साथ है कि वे पर्यावरण के साथ कैसे बातचीत करते हैं, अन्य संसाधन (व्यापार के अलावा जो आपने कवर किया है) या खिलाड़ी तो विकल्प दो नए लोगों को बहुत आसान बनाता है।

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

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