मैं पुनः आरंभ किए बिना एक विकल्प स्क्रीन से प्रदर्शन सेटिंग्स कैसे अपडेट कर सकता हूं?


9

मैं वर्तमान में Allegro 5 और बढ़ावा देने के साथ C ++ 11 में एक 2D आरपीजी बना रहा हूं।

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

कृपया ध्यान दें कि मैं विकल्पस्क्रीन से सीधे अपने गेम ऑब्जेक्ट को कॉल करने के लिए आवश्यक नहीं हूं। धराशायी लाइन केवल उस प्रभाव को स्पष्ट करने के लिए है जिसे मैं प्राप्त करने की कोशिश कर रहा हूं; जब किसी विकल्प को सिस्टम के एक अलग हिस्से में बदला जाता है तो किसी तरह गेम को अपडेट किया जा सकता है।

विस्तृत विवरण

स्क्रीन मैनजर में GameScreenवर्तमान में मौजूद सभी वस्तुओं की एक सूची है। ये पॉपअप सहित गेम में विभिन्न स्क्रीन होंगे। यह डिजाइन C # / XNA में कमोबेश गेम स्टेट मैनेजमेंट के नमूने का पालन ​​करता है ।

ScreenManagerमेरी का संदर्भ होता है Gameवस्तु। Gameवस्तु initializes और संशोधित खेल की सेटिंग। यदि मैं रिज़ॉल्यूशन बदलना चाहता हूं, तो फुलस्क्रीन पर जाएं, या वॉल्यूम को म्यूट करें जो मैं Gameकक्षा में ऐसा करूंगा ।

हालाँकि, OptionsScreen वर्तमान में गेम क्लास तक नहीं पहुँच सकता। नीचे देखें आरेख:

एक गेमस्क्रीन तीन घटनाओं का संकेत दे सकता है onFinished, onTransitionStartऔर onTransitionEnd। ऐसा नहीं है onOptionsChangedक्योंकि केवल एक स्क्रीन ऐसा करती है। ScreenManager ईवेंट हैंडलिंग को उसके लिए सेट-अप नहीं कर सकता क्योंकि यह सभी स्क्रीन को GameScreens के रूप में हैंडल करता है ।

मेरा सवाल है, मैं अपना डिज़ाइन कैसे बदल सकता हूं ताकि OptionsMenu में बदलाव के लिए पुनरारंभ की आवश्यकता न हो, लेकिन तुरंत बदल दिया जाए? Gameएक बार लागू बटन पर क्लिक करने के बाद मैं अपनी वस्तु को अपडेट करने का अनुरोध करूंगा ।


यह सवाल (भले ही यह खेल से संबंधित है) programmers.stackexchange.com के लिए एक सही फिट की तरह दिखता है, क्योंकि यह सामान्य ओओ डिज़ाइन के बारे में वास्तविक गेम की तुलना में अधिक है
bughi

आपको इस तरह के भयानक दिखने वाले रेखांकन कहाँ से मिलेंगे?
जौटलमोड

@psycketom: पहला Visio 2013 का है और दूसरा VS2012 के कोड से जेनरेट किया गया है। उम्मीद है की वो मदद करदे!
IAE

जवाबों:


1

मैंने जो देखा है, उसमें से सबसे आसान तरीका है स्टार्टअप पर वर्तमान प्रदर्शन सेटिंग्स निर्धारित करने के लिए एक विकल्प फ़ाइल; फिर, जब आपकी विकल्प स्क्रीन प्रदर्शित होती है, तो सभी मौजूदा विकल्पों को एक फ़ाइल से लोड करें।

जब परिवर्तनों को एक बटन applyया okबटन के माध्यम से अंतिम रूप दिया जाता है , तो वे एक फ़ाइल में वापस सहेजे जाते हैं। यदि कोई परिवर्तन प्रदर्शन को प्रभावित करता है, तो उपयोगकर्ता को सूचित करें कि उन्हें प्रभावी होने के लिए खेल को फिर से शुरू करना होगा।

जब खेल को फिर से शुरू किया जाता है, तो (अब नई) प्रदर्शन सेटिंग्स फिर से फ़ाइल से पढ़ी जाती हैं।

--EDIT--

अनंद ... अगर मैं उस आखिरी वाक्य पर ध्यान देता तो यह मदद करता। आपको पुनः आरंभ नहीं करना है। आपके कार्यान्वयन और आपके बैक-एंड ग्राफ़िक्स लाइब्रेरी के आधार पर चीज़ों को थोड़ा और कठिन बनाता है।

IIRC, एलेग्रो में एक फ़ंक्शन कॉल है जो आपको मक्खी पर प्रदर्शन सेटिंग्स को बदलने की अनुमति देता है। मैं अभी तक Allegro 5 पर अप-एंड-अप नहीं हूं, लेकिन मुझे पता है कि आप 4 में कर सकते हैं।


मुझे नहीं लगता कि यह मुद्दा एलेग्रो और इसकी क्षमताओं से संबंधित है। "मेरा सवाल है, मैं अपना डिज़ाइन कैसे बदल सकता हूं ताकि OptionsMenu में बदलाव के लिए पुनरारंभ की आवश्यकता न हो, लेकिन तुरंत बदल दिया जाए?" पुनरारंभ इसलिए है क्योंकि "OptionsScreen वर्तमान में गेम क्लास तक नहीं पहुंच सकता है" और अगर मुझे सही ढंग से समझ में आता है तो उन्हें सेटिंग फ़ाइल से लोड करना होगा।
क्लासिकथंडर

@ कैसी: हैलो केसी! :) हाँ, मैं प्रासंगिक प्रदर्शन डेटा संग्रहीत करने के लिए एक कॉन्फ़िगरेशन फ़ाइल का उपयोग कर रहा हूं, लेकिन मैं पुनरारंभ से बचने में सक्षम होना चाहता हूं। यह एक छोटा गेम है, और अन्य गेम रिज्यूलेशन को पुनरारंभ किए बिना बदल सकते हैं, इसलिए मैं यह नहीं देखता कि मुझे उपयोगकर्ता को अपने साथ पुनरारंभ करने के लिए क्यों मजबूर करना चाहिए। यह एक प्रयोज्य मुद्दा है। जब मैं सिर्फ एलेग्रो डिस्पे फ़ंक्शंस को कॉल कर सकता था, तो मैं OOP बने रहने की कोशिश कर रहा हूं और अपने ग्राफिक्स कॉल्स को सिर्फ इसलिए नहीं मिला सकता क्योंकि मैं कर सकता हूं; मैं उस अच्छे डिजाइन पर विचार नहीं करता।
IAE

मैंने "बिना रिस्टार्ट" बिट पर प्रकाश डाला ताकि अन्य समान अंतिम वाक्य पर यात्रा न करें। इस तरह के एक महत्वपूर्ण तथ्य को अंत में नहीं आना चाहिए था, मैं माफी मांगता हूं):
IAE

@SoulBeaver कौन कहता है कि आपको इसे बनाना चाहिए ताकि आप पुनः आरंभ न करें? यह एक व्यवहार्य बात है कि इसकी आवश्यकता है, वास्तव में यह अब और अधिक आम हो रहा है । कुछ हालिया रिलीज़ (XCOM: शत्रु अज्ञात, Skyrim, आदि) बड़े बजट के खेल को पुनः आरंभ करने की आवश्यकता होती है। (तथ्य यह है कि वे स्टीम पर हैं, इसके सर्वर-साइड विकल्पों के समन्वय के कारण अपराधी हो सकते हैं लेकिन चलो वहां नहीं जाते ...)
केसी

1
@ कैसी: सच है, और कुछ विकल्पों के लिए मैं देख सकता हूं कि यह क्यों आवश्यक है, लेकिन फुलस्क्रीन / विंडो वाली या स्क्रीन रिज़ॉल्यूशन जैसी चीजों के लिए? मैंने कभी भी ऐसा खेल नहीं देखा है जिसमें उन सेटिंग्स के लिए पुनरारंभ की आवश्यकता हो। मेरा मूल प्रश्न है: मुझे अपने उपयोगकर्ता को पुनरारंभ करने के लिए क्यों मजबूर करना चाहिए जब गेम स्वचालित रूप से सेटिंग्स बदल सकता है?
IAE

1

यही मैं अपने खेल के लिए करता हूं। सामान को इनिशियलाइज़ करने के लिए मेरे पास 2 अलग-अलग कार्य हैं, 'इनिट' और 'रीसेट'। Init को केवल एक बार स्टार्टअप पर बुलाया जाता है और वे चीजें करते हैं जो किसी भी सेटिंग पर निर्भर नहीं होते हैं, जैसे कि मुख्य संपत्ति लोड करना। रीसेट, स्क्रीन रिज़ॉल्यूशन के आधार पर UI को बिछाने जैसी चीजें करता है, इसलिए हर बार सेटिंग्स में बदलाव को कहा जाता है।

init();
bool quit = false;
while( !quit )
{
    createWindow();
    reset();

    bool settings_changed = false;
    while( !quit && !settings_changed )
    {
        ... main loop
        // set quit=true if user clicks 'quit' in main menu
        // set settings_changed=true if user clicks 'apply' in options
    }

    destroyCurrentWindow();
}

मैं एलेग्रो से परिचित नहीं हूं, लेकिन मेरा जवाब काफी सामान्य है, इसलिए मुझे उम्मीद है कि यह आपकी या किसी और की भी इसी तरह की समस्या से निजात दिलाएगा।


यह एक दिलचस्प उपाय है। जब भी कोई रीसेट कहा जाता है, मैं एक तंग नियंत्रण रखने की कोशिश कर रहा था, लेकिन आप इसे एक बदलाव की परवाह किए बिना करते हैं। यह निश्चित रूप से कुछ है जिसे मैं लागू कर सकता हूं, और मैं इसे देखूंगा, धन्यवाद!
IAE

1

आपकी वर्तमान वास्तुकला को गड़बड़ाने के बिना, मुझे दो तरीके दिखाई देते हैं। सबसे पहले, आप कक्षा Gameमें उदाहरण के लिए एक पॉइंटर स्टोर कर सकते हैं OptionsScreen। दूसरा, आप Gameकिसी दिए गए अंतराल में वर्तमान सेटिंग्स को प्राप्त कर सकते हैं, हर सेकंड कहते हैं।

वास्तव में नई सेटिंग्स के अनुकूल होने के लिए, Gameक्लास को कुछ प्रकार के रीसेट फ़ंक्शंस लागू करने होते हैं जो वर्तमान सेटिंग्स को प्राप्त करते हैं और उन पर आधारित रीइंस्ट्रक्ट करते हैं।

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

वैश्विक इवेंट मैनेजर के साथ, OptionsScreenविश्व स्तर पर एक रेड्रा इवेंट को आग लगा सकता है जिसने Gameपहले सुनने के लिए पंजीकृत किया है।

आम तौर पर आप एक हैश मैप में उन्हें सुनते हुए इवेंट्स और कॉलबैक स्टोर करने वाले मैनेजर क्लास को लागू कर सकते हैं। फिर आप उस प्रबंधक का एक एकल उदाहरण बना सकते हैं और उसे अपने घटकों को इंगित कर सकते हैं। नए C ++ का उपयोग करना काफी आसान है क्योंकि आप std::unordered_mapहैश मैप के रूप में उपयोग कर सकते हैं और std::functionकॉलबैक स्टोर कर सकते हैं । विभिन्न दृष्टिकोण हैं जो आप कुंजी के रूप में उपयोग कर सकते हैं। उदाहरण के लिए, आप इवेंट मैनेजर स्ट्रिंग को आधार बना सकते हैं जो घटकों को और अधिक स्वतंत्र बनाता है। उस स्थिति में आप std::stringहैश मानचित्र में कुंजी के रूप में उपयोग करेंगे। मुझे व्यक्तिगत रूप से यह पसंद है और यह निश्चित रूप से कोई प्रदर्शन मुद्दा नहीं है, लेकिन अधिकांश पारंपरिक इवेंट सिस्टम कक्षाओं के रूप में घटनाओं के साथ काम करते हैं।


नमस्ते दानीजर। मैं पहले से ही बढ़ावा :: संकेतों का उपयोग कर एक अल्पविकसित घटना से निपटने की योजना स्थापित कर रहा हूँ। GameScreen से लेकर ScreenManager तक की मजबूत रेखा वास्तव में उस घटना से निपटने वाली है। क्या आपके पास वैश्विक इवेंट मैनेजर की वास्तुकला का विवरण देने वाले कोई संसाधन हैं? अधिक काम या नहीं, यह लगता है कि यह एक स्वच्छ कार्यान्वयन के लिए नेतृत्व कर सकता है।
IAE

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

1

खैर, यह ऑब्जर्वर पैटर्न का कुछ विशिष्ट मामला है।

एक समाधान है जिसमें कॉलबैक शामिल है। यदि आप ढीले युग्मन चाहते हैं, तो ऐसा करने का यह सबसे अच्छा तरीका है और मुझे लगता है कि यह सबसे साफ भी है। इसमें कोई वैश्विक प्रबंधक या एकल शामिल नहीं होंगे।

मूल रूप से, आपको कुछ प्रकार की आवश्यकता होगी SettingsStore। वहां आप सेटिंग्स स्टोर करते हैं। जब आप एक नई स्क्रीन बनाते हैं तो उन्हें स्टोर के लिए एक पॉइंटर की आवश्यकता होगी। इस मामले में OptionsScreenयह कुछ सेटिंग्स मानों को ही संशोधित करेगा। के मामले में GameScreenयह सिर्फ उन्हें पढ़ा जाएगा। तो, अपने खेल में आप सिर्फ एक उदाहरण बनाएंगे, जिसे सभी स्क्रीन के साथ पारित किया जाएगा जो एक की आवश्यकता होती है।

अब, उस SettingsStoreवर्ग के पास एक सूची होगी notifiables। वे कक्षाएं हैं जो एक निश्चित ISettingChangedइंटरफ़ेस को लागू करती हैं । इंटरफ़ेस एक सरल होगा जिसमें निम्न विधि शामिल होगी:

void settingChanged(std::string setting);

फिर आपकी स्क्रीन में आप उस प्रत्येक सेटिंग के लिए तर्क को लागू करेंगे जिसकी आप परवाह करते हैं। फिर, सूचित करने के लिए अपने आप को स्टोर में जोड़ें store->notifyOnChange(this);:। जब कोई सेटिंग बदली जाती है, तो सेटिंग नाम के साथ कॉलबैक कहा जाता है। नया सेटिंग मान फिर से प्राप्त किया जा सकता है SettingsStore

अब, इसे निम्नलिखित विचारों के साथ आगे बढ़ाया जा सकता है:

  • एक वर्ग का उपयोग करें जो सेटिंग्स स्ट्रिंग्स को संग्रहीत करता है - SettingsStoreआसपास भी कॉपी-पेस्टिंग स्ट्रिंग्स को रोकने के लिए (कास्ट स्ट्रिंग्स) हो सकता है ।
  • एक स्ट्रिंग के बजाय और भी बेहतर, यह निर्दिष्ट करने के लिए कि आपके पास क्या सेटिंग्स है, एक एनम का उपयोग करें
  • आप कॉलबैक में तर्क के रूप में पुराने और नए मूल्यों को भी निर्दिष्ट कर सकते हैं, लेकिन यह अधिक जटिल होगा, क्योंकि आपके पास स्ट्रिंग या इंट वैल्यू या व्हाट्सएप हो सकता है। यह आप पर निर्भर करता है।

0

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

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