अद्यतन करने के लिए टर्न-आधारित (आरपीजी) खेलों में निष्क्रिय समय का उपयोग करना


9

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

हालांकि, यह तुरंत सुझाव देता है कि इसे थ्रेडेड करने की आवश्यकता होगी। क्या एक ही धागे में इस तरह का डिज़ाइन संभव है?

loop:  
if not check_something_pressed:  
    update_a_very_small_amount  
else  
  keep going

लेकिन अगर हम कहते हैं कि 'a_very_small_amount' प्रत्येक लूप में केवल एक ही ऑब्जेक्ट को अपडेट कर रहा है, तो यह अपडेट करने में बहुत धीमा होने वाला है।

आप इस बारे में कैसे जाएंगे, अधिमानतः एक ही धागे में?

संपादित करें: मैंने इस भाषा-अज्ञेय को टैग किया है क्योंकि यह समझदारी वाली बात लगती है, हालांकि पायथन के लिए कुछ भी अधिक विशिष्ट होगा। ;-)

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

जवाबों:


7

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

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

फ्रेम के प्रसंस्करण समाप्त हो जाने के बाद, अंतिम फ्रेम के अंत के लिए संग्रहीत समय के लिए 16.667 एमएस जोड़ें, यह पता लगाने के लिए कि अगले फ्रेम का अंत कहां होना चाहिए। यदि आप वर्तमान समय + 16.667 एमएस का उपयोग करते हैं और प्रसंस्करण खत्म हो जाता है, तो अगले फ्रेम के अंत को बाहर धकेल दिया जाएगा, हालांकि अंतिम फ्रेम खत्म हो गया है।

पुन: दूसरा संपादित करें

स्पष्ट करने के लिए, मैं मुख्य लूप के माध्यम से एक पुनरावृत्ति को इंगित करने के लिए यहां फ्रेम-दर शब्द का उपयोग करता हूं। यदि यह उपयोगकर्ता की इनपुट गति के आधार पर है, तो मुझे लगता है कि आपका लक्ष्य केवल खेल को संवेदनशील बनाना है। अन्यथा आप केवल इनपुट की जांच कर सकते हैं और हर बार लूप के माध्यम से हर बार अपडेट कर सकते हैं, भले ही ऐसा करने में 10 सेकंड लगें। हालांकि इसे उत्तरदायी महसूस करने के लिए, आप संभवतः प्रति सेकंड 20 बार इनपुट की जांच करना चाहेंगे, जो कि 20 एफपीएस की प्रभावी फ्रेम दर देता है, भले ही आप वास्तव में इन फ़्रेमों को आकर्षित नहीं कर रहे हों। इससे पहले कि आप इनपुट के लिए फिर से जाँच करने के लिए चीजों को अपडेट करने के लिए यह आपको 50 एमएस देगा।


2

के लिए अजगर विशेष रूप से आप कोशिश करते हैं और उपयोग कर सकते हैं Coroutines कई अद्यतन कॉल पर गणना करने के लिए।

... कोरआउट प्रोग्राम घटक होते हैं जो सबरूटीन्स को सामान्य बनाते हैं और कुछ स्थानों पर निष्पादन को निलंबित करने और फिर से शुरू करने के लिए कई प्रवेश बिंदुओं की अनुमति देते हैं ...

PyPon में PEP-0342 विवरण कोरूटाइन कार्यान्वयन।

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


1

हाँ यह संभव है। आपके गेम में किसी प्रकार का मुख्य गेम लूप होगा। कुछ इस तरह:

while(gameRunning)
{
  checkUserInput()
  updateGame()
  renderGame()
}

UpdateGame में आप अपनी गेम ऑब्जेक्ट्स पर पुनरावृति कर सकते हैं और उन्हें "थोड़ा" अपडेट कर सकते हैं। यदि आप इस पद्धति में कोई भारी गणना कर रहे हैं तो खेल बस लटका रहेगा। तो आपको गेम लूप के कई पुनरावृत्तियों पर चलने के लिए इन गणनाओं को विभाजित करने का एक तरीका चाहिए।

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

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

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


1

जिस तरह से मैं आपके प्रश्न को समझ रहा हूं वह यह है कि मूल रूप से आप सहकारी मल्टीटास्किंग के बारे में पूछ रहे हैं।

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

एक बेहतर सवाल, मेरी राय में, खिलाड़ी के स्थानांतरित होने की प्रतीक्षा करते समय क्या करना है। किस तरह की चीजें इतनी प्रोसेसर-इंटेंसिव होंगी कि वे वैसे भी मक्खी पर नहीं कर सकते हैं, जबकि, एक ही समय में, इतना वैकल्पिक होने के नाते कि अगर खिलाड़ी बस कुछ तेजी से आगे बढ़ता है, तो गेम नहीं होता है इन्हें संसाधित करने का समय। इस प्रकार, कुछ हज़ार AI के लिए A * की गणना करने जैसा सामान बाहर है।

मेरी राय में, बेहतर समाधान, बस उपज / नींद लेना है, और कंप्यूटर के बिजली प्रबंधन को अपना काम करने देना है। लैपटॉप उपयोगकर्ता आपको इसके लिए बेहतर पसंद करेंगे।

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