6

我是 iPhone 开发新手,但正在尝试构建 2D 游戏。我正在关注一本书,但它创建的游戏循环基本上是这样说的:

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

原因是这将以 30fps 运行。然而,这似乎有点精神,因为如果我的帧需要 1/30 秒,那么它将以 15fps 运行(因为它会花费与更新一样多的时间休眠)。

因此,我进行了一些挖掘并找到了 CADisplayLink 类,它将对我的 gameLoop 函数的调用同步到刷新率(或它的一小部分)。我找不到它的很多示例,所以我在这里发布代码审查:-) 它似乎按预期工作,它包括将经过(帧)时间传递给 Update 方法,所以我的逻辑可以是帧率-独立(但是我实际上无法在文档中找到如果我的框架花费的时间超过其允许的运行时间,CADisplayLink 会做什么 - 我希望它只是尽力赶上,并且不会崩溃!)。

//
//  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

对于任何反馈,我们都表示感谢 :-)

PS。如果你能告诉我为什么所有的书都使用“viewController.view”,而其他所有的书似乎都使用“[对象名称]”格式,那就加分吧。为什么不 [viewController 视图]?

4

2 回答 2

2

您在问题中将 Cocos2D 列为标签,但您实际上并未使用任何 Cocos2D 代码。你考虑过为你的游戏做一个 Cocos2D 实现吗?它将为您节省一些不必要的麻烦。

至于您的语法问题[myObject view]用于调用方法,myObjectmyObject.view用于设置/获取作为属性公开的实例变量。我不记得您是否也可以使用检索实例变量[myObject view],但如果可行,那么我猜两者之间的唯一区别是语法,您可以使用这两种方法来检索实例变量。

希望其中的一些杂谈对你有用。

于 2010-03-11T20:28:59.333 回答
-2

从 Apple 的许多 GL 示例中,我认为您应该使用计时器。

animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/60.0)
                                                  target:self
                                                selector:@selector(updateAndRender)
                                                userInfo:nil
                                                 repeats:TRUE];
于 2010-04-12T08:47:27.597 回答