मैं आईफोन देव के लिए नया हूं, लेकिन 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 देखें]?
हालांकि यह कोड काम करता है, ऐसा लगता है कि यह थोड़ा सा है। Framerate कम नहीं है, यह बस चिकनी प्रतीत नहीं होता है। मुझे लगता है कि ऐसा इसलिए हो सकता है क्योंकि मैं अपने गेम लूप में framerate और फिर * अद्यतन * के लिए समन्वयित कर रहा हूँ। प्रतिपादन drawRect में किया जाता है। मुझे लगता है कि मेरा कोड सीधे विधि में चित्रित होना चाहिए (और संभवतः ड्रॉ के बाद अपडेट किया जाना चाहिए), लेकिन मुझे CADisplayLink का कोई अच्छा उदाहरण नहीं मिल रहा है। –
मैंने अपने sprites के आंदोलन को प्रति सेकंड 30 पिक्सल में बदल दिया, और यह पूरी तरह से चिकनी लगता है (बहुत ही कभी-कभी फ्रेम गिरा दिया जाता है), इसलिए मुझे लगता है कि यह बस उस गति के नीचे था जो मैं निर्धारित करता था - उदाहरण के लिए। प्रति फ्रेम एक पिक्सेल से थोड़ा आगे बढ़ते हुए, जिसका मतलब है कि अंत में यह एक पिक्सेल में दो पिक्सेल कूद जाएगा, जिससे यह असमान दिखता है। मुझे लगता है कि यह अपरिहार्य है। –