2010-03-11 27 views
6

मैं आईफोन देव के लिए नया हूं, लेकिन 2 डी गेम बनाने की कोशिश कर रहा हूं। मैं एक किताब पीछा कर रहा था, लेकिन खेल पाश यह मूल रूप से बनाया ने कहा:क्या यह एक आईफोन गेम के लिए गेम लूप करने का एक अच्छा तरीका है?

function gameLoop 
    update() 
    render() 
    sleep(1/30th second) 
    gameLoop 

तर्क है कि इस 30fps पर चलाने होता था। हालांकि, यह थोड़ा मानसिक लग रहा था, क्योंकि अगर मेरा फ्रेम 1/30 वां सेकेंड लेता है, तो यह 15fps पर चलाएगा (क्योंकि यह अपडेट करने के रूप में सोते समय उतना समय व्यतीत करेगा)।

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

// 
// GameAppDelegate.m 
// 
// Created by Danny Tuppeny on 10/03/2010. 
// Copyright Danny Tuppeny 2010. All rights reserved. 
// 

#import "GameAppDelegate.h" 
#import "GameViewController.h" 
#import "GameStates/gsSplash.h" 

@implementation GameAppDelegate 

@synthesize window; 
@synthesize viewController; 

- (void) applicationDidFinishLaunching:(UIApplication *)application 
{ 
// Create an instance of the first GameState (Splash Screen) 
[self doStateChange:[gsSplash class]]; 

// Set up the game loop 
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)]; 
[displayLink setFrameInterval:2]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

- (void) gameLoop 
{ 
// Calculate how long has passed since the previous frame 
CFTimeInterval currentFrameTime = [displayLink timestamp]; 
CFTimeInterval elapsed = 0; 

// For the first frame, we want to pass 0 (since we haven't elapsed any time), so only 
// calculate this in the case where we're not the first frame 
if (lastFrameTime != 0) 
{ 
    elapsed = currentFrameTime - lastFrameTime; 
} 

// Keep track of this frames time (so we can calculate this next time) 
lastFrameTime = currentFrameTime; 

NSLog([NSString stringWithFormat:@"%f", elapsed]); 

// Call update, passing the elapsed time in 
[((GameState*)viewController.view) Update:elapsed]; 
} 

- (void) doStateChange:(Class)state 
{ 
// Remove the previous GameState 
if (viewController.view != nil) 
{ 
    [viewController.view removeFromSuperview]; 
    [viewController.view release]; 
} 

// Create the new GameState 
viewController.view = [[state alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self]; 

// Now set as visible 
[window addSubview:viewController.view]; 
[window makeKeyAndVisible]; 
} 

- (void) dealloc 
{ 
[viewController release]; 
    [window release]; 
    [super dealloc]; 
} 

@end 

किसी भी प्रतिक्रिया :-)

पी एस की सराहना की जाएगी। बोनस पॉइंट्स यदि आप मुझे बता सकते हैं कि सभी पुस्तकें "viewController.view" क्यों उपयोग करती हैं लेकिन बाकी सब कुछ "[ऑब्जेक्ट नेम]" प्रारूप का उपयोग करने लगती है। क्यों नहीं [ViewController देखें]?

+0

हालांकि यह कोड काम करता है, ऐसा लगता है कि यह थोड़ा सा है। Framerate कम नहीं है, यह बस चिकनी प्रतीत नहीं होता है। मुझे लगता है कि ऐसा इसलिए हो सकता है क्योंकि मैं अपने गेम लूप में framerate और फिर * अद्यतन * के लिए समन्वयित कर रहा हूँ। प्रतिपादन drawRect में किया जाता है। मुझे लगता है कि मेरा कोड सीधे विधि में चित्रित होना चाहिए (और संभवतः ड्रॉ के बाद अपडेट किया जाना चाहिए), लेकिन मुझे CADisplayLink का कोई अच्छा उदाहरण नहीं मिल रहा है। –

+0

मैंने अपने sprites के आंदोलन को प्रति सेकंड 30 पिक्सल में बदल दिया, और यह पूरी तरह से चिकनी लगता है (बहुत ही कभी-कभी फ्रेम गिरा दिया जाता है), इसलिए मुझे लगता है कि यह बस उस गति के नीचे था जो मैं निर्धारित करता था - उदाहरण के लिए। प्रति फ्रेम एक पिक्सेल से थोड़ा आगे बढ़ते हुए, जिसका मतलब है कि अंत में यह एक पिक्सेल में दो पिक्सेल कूद जाएगा, जिससे यह असमान दिखता है। मुझे लगता है कि यह अपरिहार्य है। –

उत्तर

2

आपके पास आपके प्रश्न में टैग के रूप में सूचीबद्ध कोकोस 2 डी है लेकिन आप वास्तव में किसी भी कोकोस 2 डी कोड का उपयोग नहीं कर रहे हैं। क्या आपने अपने गेम के लिए कोकोस 2 डी कार्यान्वयन करने पर विचार किया है? यह आपको कुछ अनियंत्रित परेशानी बचाएगा।

अपने वाक्य रचना सवाल [myObject view] का सवाल है myObject पर तरीकों बुला जबकि myObject.view की स्थापना/गुण के रूप में सामने आ रहा उदाहरण चर प्राप्त करने के लिए प्रयोग किया जाता है के लिए प्रयोग किया जाता है। मुझे याद नहीं है कि क्या आप [myObject view] का उपयोग करके इंस्टेंस चर को पुनर्प्राप्त कर सकते हैं, लेकिन यदि यह काम करता है तो मुझे लगता है कि दोनों के बीच एकमात्र अंतर वाक्यविन्यास है और आप इंस्टेंस चर को पुनः प्राप्त करने के लिए दोनों विधियों का उपयोग कर सकते हैं।

आशा है कि उस रैंपिंग में से कुछ आपके लिए उपयोगी है।

+0

ओह! आपको बताया कि मैं नहीं जानता था कि मैं क्या कर रहा था! अब टैग हटा दिया गया। क्या कुछ वाक्यविन्यास चीज़ पर पढ़ रहे थे, अब इसे बेहतर समझें। लगता है कि [myclass संपत्ति] और myclass.property विभिन्न चीजें कर सकते हैं। पहला एक प्रॉपर्टी है (जो कोड निष्पादित कर सकती है, हालांकि ज्यादातर मामलों में मुझे संदेह है कि यह केवल वैरिएबल देता है) जबकि डॉट वैरिएबल को सीधे एक्सेस कर रहा है (और कस्टम कोड नहीं होगा)। एक निजी क्षेत्र और सी # में एक संपत्ति को उजागर करने के बीच अंतर की तरह लगता है, केवल यही है कि वे दोनों एक ही नाम के रूप में दिखाई दे सकते हैं! –

+0

वास्तव में, अब मैं उलझन में हूँ, क्योंकि मैं त्रुटियों हो रही है: तक पहुँचने अज्ञात 'रेक्ट' गेटर विधि मुझे लगता है कि डॉट का उपयोग कर वास्तव में प्राप्त/सेट तरीकों का उपयोग कर के रूप में ही है बनाता है कौन! –

+0

यदि आप डॉट का उपयोग करते हैं तो आपको उस इंस्टेंस वैरिएबल को परिभाषित करने की आवश्यकता होती है जिसे आप एक प्रॉपर्टी के रूप में पुनर्प्राप्त करना चाहते हैं और फिर इसे संश्लेषित करना चाहते हैं। "@property" और "@synthesize" कॉल के लिए लुकअप सिंटैक्स। गेटटर/सेटर विधियां आपके लिए अंतर्निहित रूप से बनाई गई हैं, लेकिन केवल @ सिंथेसाइज़ का उपयोग करने के बाद। यही कारण है कि आप एक अज्ञात 'रेक्ट' गेटटर विधि प्राप्त कर रहे हैं। –

-2

ऐप्पल द्वारा कई जीएल उदाहरण से, मुझे लगता है कि आपको टाइमर का उपयोग करना चाहिए।

animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/60.0) 
                target:self 
               selector:@selector(updateAndRender) 
               userInfo:nil 
               repeats:TRUE]; 
+0

मेरा मानना ​​है कि CADisplayLink को बेहतर तरीके से जोड़ा गया था, लेकिन क्योंकि इसे हाल ही में जोड़ा गया था, वहां छोटे दस्तावेज़/नमूने दिखाई देते हैं :( –

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