गेम-वाइड चर स्टोर करने का सबसे अच्छा तरीका


23

मेरे पास कठिनाई, संकल्प, पूर्ण-स्क्रीन, आदि जैसी चीजों के लिए एक विकल्प स्क्रीन है, लेकिन मैं रन-टाइम पर इन चरों को संग्रहीत / प्राप्त करने के लिए "सबसे अच्छा" तरीका खोजने के लिए संघर्ष कर रहा हूं।

वर्तमान में, मैंने एक Constantsवर्ग लागू किया है जिसमें सभी GameOptionएनम हैं, लेकिन मैं इन सभी विकल्पों के लिए एक डिफ़ॉल्ट कैसे चुनूं? इसके अलावा, मैं वर्तमान में चयनित एनम कैसे प्राप्त करूं?

संकल्प के बारे में, विशेष रूप से, मैंने मूल्यों को संग्रहीत करने का निर्णय लिया है, लेकिन मैं इस बात के बारे में अनिश्चित हूं कि डिफ़ॉल्ट कैसे प्राप्त किया जाए, या वर्तमान में संग्रहीत किया जाए, मान। कोई भी दिशा महान होगी; धन्यवाद! :)

namespace V1.test.RPG
{
  public class GameOptions
  {
    public enum Difficulty { EASY, MEDIUM, HARD }
    public enum Sound { ON, QUIET, OFF }
    public enum Music { ON, QUIET, OFF }
    public enum ResolutionWidth
    {
        SMALL      = 1280,
        MEDIUM     = 1366,
        LARGE      = 1920,
        WIDESCREEN = 2560
    }
    public enum ResolutionHeight
    {
        SMALL      = 800,
        MEDIUM     = 768,
        LARGE      = 1080,
        WIDESCREEN = 1080
    }
    public Boolean fullScreen = false;
  }
}

नायब: मैंने एसओ से पूछा और उन्होंने मुझे इस जगह की ओर इशारा किया। वहाँ एक टिप्पणी है, लेकिन मैं इसे करने के विभिन्न तरीकों / सबसे अधिक उपयोग किए जाने वाले तरीकों को सुनना चाहूंगा।


1
आपने सही जगह पूछा; जिसने भी आपको यहां भेजा है उससे गलती हुई थी। मैंने वैसे भी इस सवाल का जवाब दिया, लेकिन यह गेम डेवलपमेंट विशिष्ट प्रश्न नहीं है, यह एक सामान्य प्रोग्रामिंग प्रश्न है।
झूक

मैं सिर्फ एसओ धागा पढ़ता हूं; मुझे स्कॉट चैंबरलिन का जवाब पसंद है।
झूक

@ जॉकिंग मैंने उसे इस तरह से इंगित किया है कि कोई भी पहलू है जो विशेष रूप से खेल विकास के लिए हैं जो एक साधारण अनुप्रयोग से भिन्न हो सकते हैं। मुझे भी लगा कि आप लोग पहले से ही इस विषय पर एक विहित क्यू एंड ए हो सकते हैं क्योंकि यह बहुत आम है।
क्रिस हेस

ग्लोबल्स के बारे में वास्तविक प्रश्न के लिए संभावित, कृपया यह न मानें कि वहाँ प्रस्तावों का एक निश्चित सेट है।
लार्स विकलुंड

जवाबों:


32

बढ़ने की योजना:
हार्ड-कोडेड स्थिरांक छोटी परियोजनाओं के लिए ठीक हैं, लेकिन आखिरकार, जैसा कि आपका सॉफ्टवेयर आकार में बढ़ता है, आप चाहेंगे कि आप उन सेटिंग्स को बदल सकते हैं, जो सब कुछ फिर से तैयार किए बिना। गेम चलने के दौरान कई बार आप सेटिंग्स बदलना चाहेंगे और आप हार्ड-कोडेड कॉन्स्टेंट के साथ ऐसा नहीं कर सकते।

CVars:
एक बार जब आपका प्रोजेक्ट बढ़ता है, तो आप CVAR पर एक नज़र डालना चाहते हैं । सीवीएआर एक "स्मार्ट वेरिएबल" है, इसलिए बोलने के लिए, जिसे आप कंसोल, टर्मिनल या यूआई के माध्यम से रन-टाइम के दौरान संशोधित कर सकते हैं। सीवीएआर को आमतौर पर एक वस्तु के संदर्भ में लागू किया जाता है जो एक अंतर्निहित मूल्य को लपेटता है। फिर, ऑब्जेक्ट मान को ट्रैक करने के साथ-साथ फ़ाइल से / से लोड / सेव कर सकता है। आप एक नाम या अन्य विशिष्ट पहचानकर्ता के साथ उन्हें एक्सेस करने के लिए CVAR ऑब्जेक्ट्स को एक मैप में स्टोर कर सकते हैं।

अवधारणा को थोड़ा आगे बढ़ाने के लिए, निम्नलिखित छद्म कोड एक CVAR प्रकार का एक सरल उदाहरण है जो एक intमान को लपेटता है :

// just some flags to exemplify:
enum CVarFlags {
    CVAR_PERSISTENT, // saved to file once app exits
    CVAR_VOLATILE    // never saved to file
};

class CVar {
public:
    // the constructor registers this variable with the global list of CVars
    CVar(string name, int value, int defaultValue, int flags);

    int getValue();
    void setValue(int v);
    void reset(); // reset to the default value

    // etcetera...

private:
    int flags; // flags like: save-to-file, etc.
    int value; // the actual value
    int defaultValue; // the default value to reset the variable to
};

// global list of all CVars:
map<string, CVar> g_cvars;

वैश्विक पहुंच:
ऊपर दिए गए उदाहरण में, मैंने मान लिया है कि कंस्ट्रक्टर CVarहमेशा वैश्विक cvarsमानचित्र के साथ चर को पंजीकृत करता है ; यह काफी उपयोगी है, क्योंकि यह आपको एक चर घोषित करने की अनुमति देता है:

CVar my_var = new CVar("my_var", 0, 42, CVAR_PERSISTENT);

वह चर स्वचालित रूप से वैश्विक मानचित्र में उपलब्ध कराया जाता है और आप चर के नाम के साथ मानचित्र को अनुक्रमित करके इसे कहीं और से भी एक्सेस कर सकते हैं:

CVar v = g_cvars.find("my_var");

दृढ़ता:
जब खेल बंद हो रहा है, तो नक्शे को पुनरावृत्त करें और CVAR_PERSISTENTएक फ़ाइल के रूप में चिह्नित सभी चर को बचाएं । अगली बार जब खेल शुरू होता है, तो उन्हें फिर से लोड करें।

मामला कानून:
एक मजबूत सीवीएआर प्रणाली के अधिक विशिष्ट उदाहरण के लिए, डूम 3 में चित्रित कार्यान्वयन को देखें ।


4

अच्छी तरह से पहले एक एनम परिभाषित करता है कि मान क्या हो सकते हैं , न कि मान क्या हैं । इस प्रकार आपको एनम घोषित करने के बाद भी आपको एक और चर घोषित करने की आवश्यकता है। उदाहरण के लिए:

public enum Sound
{
    ON,
    QUIET,
    OFF
}

public Sound soundValue;

इस उदाहरण में, अब आप soundValueON, QUIET या OFF पर सेट कर सकते हैं ।


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


1

glampert समाधान बहुत पूर्ण है, लेकिन मैं अपना व्यक्तिगत अनुभव जोड़ूंगा।

मैं इसी समस्या में भाग गया, और मेरा समाधान एक स्थिर चर वर्ग का उपयोग करना था।

वेरिएबल्स वर्ग आंतरिक रूप से स्ट्रिंग से स्ट्रिंग तक एक नक्शा रखता है (अब तक मेरे सभी चर केवल तार हैं) और गेटर्स और सेटर के माध्यम से पहुँचा जा सकता है।

मुद्दा यह है कि वैश्विक चर तक पहुंच प्राप्त करना सभी प्रकार की सूक्ष्म त्रुटियों को पेश कर सकता है क्योंकि कोड के पूरी तरह से असंबंधित हिस्से अचानक एक दूसरे के साथ हस्तक्षेप कर रहे हैं।

इससे बचने के लिए, मैंने निम्नलिखित शब्दार्थ को लागू किया: setविधि का उपयोग एक अपवाद को फेंकता है अगर उस नाम वाला एक चर पहले से ही शब्दकोश में मौजूद है, और getइसे वापस करने से पहले चर को शब्दकोश से हटा देता है।

दो अतिरिक्त तरीके प्रदान करते हैं कि आप क्या उम्मीद करेंगे, setAndOverwriteऔरgetAndKeep । अन्य विधियों के शब्दार्थ की बात यह है कि आप इस तरह की त्रुटियों को आसानी से देख सकते हैं "यह विधि इस चर को शुरू करने के लिए माना जाता है, लेकिन अन्य विधि ने पहले किया था"।

डिक्शनरी को इनिशियलाइज़ करने के लिए, शुरुआती वेरिएबल्स को एक json फाइल में स्टोर किया जाता है, और फिर खेल शुरू होने पर पढ़ा जाता है।

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

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