2012-07-25 15 views
17

तो मैं अपना पहला आईओएस गेम के बीच हूं और ऑब्जेक्ट आंदोलन को एकीकृत करने के सर्वोत्तम तरीके के बारे में सोच रहा हूं।NSTimer बनाम CACurrentMediaTime()

खेल तेजी से चलती वस्तुओं और निरंतर, तेज़ उपयोगकर्ता इनपुट परिवर्तनों पर भारी निर्भर करता है। इस प्रकार, मैं ऑब्जेक्ट एकीकरण और बाधा सॉल्वर जितना संभव हो सके तेज़ी से और सटीक रूप से चलाने की कोशिश कर रहा हूं (लगातार गेम लूप कॉल के बीच उपयोगकर्ता इनपुट परिवर्तन को कम करने के लिए)।

अधिक विशेष रूप से, मैं एनएसटीमर वर्ग और CACurrentMediaTime() फ़ंक्शन की क्षमताओं से अनिश्चित हूं। अनुभवी परीक्षण करना मुश्किल है क्योंकि मुझे यकीन नहीं है कि बड़ी त्रुटि क्या है। उदाहरण के लिए, 0.008 (~ 2updates/स्क्रीन रीफ्रेश) के दोहराने वाले अंतराल के साथ एनएसटीमर का उपयोग करना और लगातार कॉल पर CACurrentMediaTime() को कॉल करना, मुझे लगता है कि कॉल के बीच समय अंतराल 0.0075 - 0.00 9 से भिन्न होता है। कहना मुश्किल है कि (छोटे) असंगतता के लिए जिम्मेदार है। ऐसे में उसके कदम का निर्धारण करने के लिए मैं होना चाहिए:

  1. मान लें NSTimer लगातार बीच के समय अंतराल निर्धारित करने के लिए पर्याप्त रूप से सटीक खेल पाश समय कदम

  2. उपयोग CACurrentMediaTime() के रूप में NSTimer समय अंतराल का उपयोग करना है खेल लूप कॉल।

छात्र और इस सब के लिए नया - कृपया अच्छा रहें :) किसी भी सलाह की बहुत सराहना की जाती है। आपके समय के लिए धन्यवाद।

उत्तर

35

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

CACurrentMediaTime() टाइमर नहीं है। यह सिस्टम में सबसे सटीक समय समारोह के चारों ओर एक रैपर है: mach_absolute_time()। इसलिए यदि आप वास्तव में परवाह करते हैं कि यह अभी कितना समय है, और आप इसे मानव-समझने योग्य संख्या में चाहते हैं, CACurrentMediaTime() आपका कार्य है। mach_absolute_time() आपको वास्तव में एक सटीक संख्या देगा, लेकिन यह Mach absolute time unit पर आधारित है जो वास्तव में किसी भी चीज के लिए मैप नहीं करता है (और प्रत्येक सीपीयू का एक अलग पैमाने होता है)। यही कारण है कि हमारे जीवन को आसान बनाने के लिए हमारे पास CACurrentMediaTime() है।

ठीक है, इसलिए NSTimer रीयल-टाइम के लिए नहीं है, और CACurrentMediaTime() टाइमर नहीं है। एक गेम प्रोग्रामर क्या करना है?

Grand Central Dispatch हमारे पास "इस समय इस समय के बारे में इस प्रणाली को चलाने के लिए सबसे अच्छा" शामिल है। यह एक डिस्पैच स्रोत है। मैं "इस समय के बारे में" कहता हूं क्योंकि जीसीडी अभी भी वास्तव में "वास्तविक समय" नहीं है जिस तरह से आरटीओएस लोगों का मतलब है। लेकिन यह गेम डेवलपर्स के लिए वास्तविक समय है। Concurrency Programming Guide में एक टाइमर बनाने के लिए देखो। dispatch_after() पर भी एक नज़र डालें, जो एक शॉट के लिए अच्छा है "देरी के बाद इसे चलाएं।"

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

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

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

और निश्चित रूप से वहाँ GLKit, लेकिन यह एक पूरी अलग बात है ....

+3

अरे रोब, महान जवाब के लिए धन्यवाद! मैं वास्तव में आपको पढ़ने और जवाब देने के लिए समय लेने की सराहना करता हूं। धन्यवाद! विस्तृत प्रतिक्रिया के लिए –

+0

धन्यवाद! त्वरित स्पष्टीकरण: जैसा कि नीचे दिए गए एक उत्तर से पता चलता है, एनएसटीमर डॉक्स का दावा है कि टाइमर के लिए समय अंतराल का प्रभावी संकल्प 50-100 मिलीसेकंड के आदेश तक ही सीमित है। क्या आपका सुझाव अभी भी उप-दूसरे कार्यों के लिए एनएसटीमर से बचने के लिए है आज? एक बार फिर धन्यवाद! – Crashalot

+1

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

2

NSTimer documentationthe effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. के मुताबिक शायद यही कारण है कि आप समय अंतराल में भिन्नता क्यों देखते हैं।

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

संबंधित मुद्दे