2009-08-29 6 views
5

का उपयोग किये बिना आईफोन पर गेम लूप कैसे बनाते हैं Iphone में अपने गेम को साफ़ रूप से पोर्ट करने के लिए, मैं एक गेम लूप बनाने की कोशिश कर रहा हूं जो एनएसटीमर का उपयोग नहीं करता है।आईएसटी पर एनएसटीमर

मैं कुछ नमूना कोड है कि, NSTimer का उपयोग कर अगर, आप इसे शुरुआत में की तरह सेट करेंगे ऊपर कुछ के साथ में देखा

self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; 

जहां drawView कुछ ऐसा दिखाई देगा:


- (void)drawView 
{ 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    mFooModel->render(); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

जब इस तकनीक का उपयोग करके mFooModel ठीक प्रस्तुत करता है, लेकिन मैं इसके बजाय अपना खुद का गेम लूप बनाना चाहता हूं जो NSTimer कॉल ड्रॉ देखने के बजाय drawView को कॉल करता है, एक सेकंड 60 बार देखें। मुझे कुछ पसंद है:


while(gGameState != kShutDown) 
{ 
    [self drawView] 
} 

दुर्भाग्यवश जब मैं ऐसा करता हूं, तो मुझे बस एक ब्लैक स्क्रीन मिलती है। ऐसा क्यों होता है? क्या मैं वैसे भी लागू कर सकता हूं जो मैं यहां बता रहा हूं?

कारण मैं एनएसटीमर से बचना चाहता हूं क्योंकि मैं गेम लूप में भौतिकी और एआई अपडेट करना चाहता हूं। मैं अपने स्वयं के घड़ी/टाइमर का उपयोग उस समय की मात्रा को ट्रैक रखने के लिए करता हूं जो कि समाप्त हो गया है ताकि मैं इसे सही तरीके से कर सकूं। जितना तेज़ हो सके उतना तेज़ होता है। मैं this article

यह एक आवेगी सवाल का कुछ हद तक है में वर्णित के रूप कुछ तकनीकों का इस्तेमाल करने की कोशिश (एक के बाद आप पूरे दिन कोडिंग किया गया है, अटक जाते हैं, और आशा है कि इस सवाल का जवाब कर सुबह तक होती है)

चीयर्स लोग।

उत्तर

2

आप NSTimer उपयोग करने के लिए आप नहीं चाहते कि आप NSRunLoop मैन्युअल चलाने की कोशिश कर सकते हैं:

static BOOL shouldContinueGameLoop; 
static void RunGameLoop() { 
    NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; 
    NSDate *destDate = [[NSDate alloc] init]; 
    do { 
     // Create an autorelease pool 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     // Run the runloop to process OS events 
     [currentRunLoop runUntilDate:destDate]; 
     // Your logic/draw code goes here 
     // Drain the pool 
     [pool drain]; 
     // Calculate the new date 
     NSDate *newDate = [[NSDate alloc] initWithTimeInterval:1.0f/45 sinceDate:destDate]; 
     [destDate release]; 
     destDate = newDate; 
    } while(shouldContinueGameLoop); 
    [destDate release]; 
} 
+0

धन्यवाद। यह बहुत उपयोगी कोड है। – user156848

+0

मैं चेतावनी देना भूल गया था कि यदि आपके पास एक सेकंड के 1/45 वें से अधिक काम है (या उस से अधिक के लिए रनलोप स्टालों) तो आप स्टटरिंग, देरी टच इवेंट और अन्य विषम मुद्दों को रोक देंगे। अच्छी तरह से परीक्षण करना सुनिश्चित करें। इसके लिए कोड को अपडेट करना संभव है, लेकिन एप्लिकेशन विशिष्ट – rpetrich

+0

रन लूप में सभी आवंटन/dealloc प्रदर्शन को प्रभावित नहीं करता है? क्या लूप के बाहर सभी को स्थानांतरित करने का कोई तरीका है? – Andrew

21

एक अन्य विकल्प iPhoneOS 3.1 के साथ नया CADisplayLink एपीआई का उपयोग करने है। यह उस चयनकर्ता को कॉल करेगा जिसे आपने निर्दिष्ट किया है जब स्क्रीन सामग्री को अद्यतन करने की आवश्यकता है।

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(renderAndUpdate)]; 
[displayLink setFrameInterval:2]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

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

+0

क्या मुझे डिस्प्ले लिंक –

+0

NSAutoreleasePool के लिए NSAutoreleasePool जोड़ने की आवश्यकता है। एक्सकोड में एक नया ओपनजीएल आधारित प्रोजेक्ट बनाएं और आप इसका उपयोग कैसे करेंगे। –

2

कैडिसप्ले लिंक का उपयोग करते समय 3.1 आधारित गेम,
"टाइमर" का उपयोग करके कुछ भी वास्तव में एक अच्छा विचार है।

जीपीयू काम को कम करने के लिए सबसे अच्छा तरीका अच्छा पुराना "ट्रिपल बफरिंग" है।

फेबियन उसकी कयामत Iphone समीक्षा में एक बहुत अच्छा व्याख्या है:
http://fabiensanglard.net/doomIphone/

0

के बारे में CADisplayLink और iPhone के लिए कयामत फेबियन द्वारा लेख, मैं फेबियन ईमेल किया और मुझे लगता है कि सबसे अच्छा विकल्प व्यक्तिपरक है। प्रदर्शन-आधारित डिस्प्ले लिंक और ट्रिपल बफरिंग समान होना चाहिए, लेकिन डिस्प्ले लिंक केवल ओएस 3.1 पर उपलब्ध है। तो यह आपका निर्धारण कारक होना चाहिए।

2

self का उपयोग displayLinkWithTarget के लिए एक लक्ष्य के रूप में करें, मैनुअल कहता है "नया निर्मित डिस्प्ले लिंक लक्ष्य को बरकरार रखता है"। मार्टिन