游戏循环与单独的计时器,用于渲染和游戏逻辑

mik*_*ast 6 iphone timer ios

我想将游戏逻辑和渲染分成两个不同的循环,因为我不希望fps控制游戏速度.我尝试通过为渲染创建CADisplayLink以及为游戏逻辑创建NSTimer来实现此目的.但后来发生了一件奇怪的事:

有时候(15个应用程序运行中有1个)游戏以非常低的fps(大约5-10)运行,但其余时间它完全平滑.如果我删除游戏逻辑的NSTimer并将两个循环结合起来,则fps一直很高,但这显然不是一个可接受的解决方案.所以看起来有时两个计时器"相互推迟"或类似的东西,但我并不完全理解runloops的内部工作.

这是我创建计时器和displaylink的方法:

NSTimer *gameTimer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:1.0 / 60.0 target:self selector:@selector(gameTimerFired:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:gameTimer forMode:NSDefaultRunLoopMode];
[gameTimer release];

CADisplayLink *aDisplayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
[aDisplayLink setFrameInterval:animationFrameInterval];
[aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = aDisplayLink;
Run Code Online (Sandbox Code Playgroud)

你能告诉我导致fps问题的原因以及解决方法吗?

或者你能推荐任何其他解决方案来分离渲染和游戏逻辑循环吗?

And*_*mer 3

您可以使用 gameTimer 或 CADisplayLink 通过测量自上次循环以来经过的时间并使用它来增强游戏逻辑来通过一个循环来完成此操作。

所以..

NSDate *oldTime = [[NSDate date] retain];

-(void)updateGame {
    NSDate *curTime = [NSDate date];
    NSTimeInterval timePassed_ms = [curTime timeIntervalSinceDate:oldTime] * 1000.0;

    [oldTime release];
    oldTime = curTime;
    [oldTime retain];

    //use the timePassed_ms to augment your game logic.  IE: Moving a ship
    [ship moveLength:ship.velocity * timePassed_ms/1000.0];
}
Run Code Online (Sandbox Code Playgroud)

这通常是我处理此类事情的方式。我通常喜欢将更新功能直接构建到我的游戏对象中。所以更新船实际上看起来像这样:

[ship update:timePassed_mc];
Run Code Online (Sandbox Code Playgroud)