首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不使用NSTimer的情况下在iPhone上进行游戏循环

如何在不使用NSTimer的情况下在iPhone上进行游戏循环
EN

Stack Overflow用户
提问于 2009-08-29 11:43:52
回答 5查看 13K关注 0票数 5

为了干净利落地将我的游戏移植到iPhone上,我尝试创建一个不使用NSTimer的游戏循环。

我在一些示例代码中注意到,如果使用NSTimer,则需要在开始时设置如下内容

代码语言:javascript
运行
复制
    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];

其中的drawView看起来像这样:

代码语言:javascript
运行
复制
- (void)drawView 
{
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    mFooModel->render();
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

在使用这种技术时,mFooModel呈现得很好,但是我想创建自己的游戏循环来调用drawView,而不是让NSTimer每秒调用drawView 60次。我想要这样的东西:

代码语言:javascript
运行
复制
while(gGameState != kShutDown)
{
    [self drawView]
}

不幸的是,当我这样做的时候,我得到的只是一个黑屏。这一切为什么要发生?有没有什么办法可以实现我在这里描述的东西?

我想避免NSTimer的原因是因为我想在游戏循环中进行物理和AI更新。我使用自己的时钟/计时器来记录已经过去的时间,这样我就可以准确地完成这项工作。渲染速度越快越好。我尝试使用this article中描述的一些技术

这是一个有点冲动的问题(在你写了一整天的代码之后,你会遇到一个卡住的问题,希望早上就能得到答案)

干杯伙计们。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-08-29 23:31:24

如果您不想使用NSTimer,可以尝试手动运行NSRunLoop

代码语言:javascript
运行
复制
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];
}
票数 3
EN

Stack Overflow用户

发布于 2009-09-11 12:09:47

API3.1的另一个选择是使用新的CADisplayLink iPhoneOS。当需要更新屏幕内容时,这将调用您指定的选择器。

代码语言:javascript
运行
复制
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(renderAndUpdate)];
[displayLink setFrameInterval:2];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

如果您需要更多示例代码,XCode中的新OpenGL项目模板也会使用CADisplayLink。

票数 21
EN

Stack Overflow用户

发布于 2010-02-03 20:55:52

虽然使用CADisplayLink对于基于3.1的游戏来说是一个非常好的选择,

任何使用“定时器”的东西都是一个非常糟糕的主意。

最好的方法是使用古老的“三重缓冲”来解耦GPU的工作。

Fabien在他的Doom Iphone评论中有一个非常好的解释:

http://fabiensanglard.net/doomIphone/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1351234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档