1

我正在使用 XCode 为 iOS 制作游戏,但是我遇到了一个问题:

如果我使用循环,图形直到循环完成后的下一帧才会更新;所以如果例如我有这样的事情:

something.center = CGPointMake(20, something.center.y);
while(something.center.x < 50)
{
    something.center = CGPointMake(something.center.x + 1, something.center.y);
    // Just a delay:
    [NSThread sleepForTimeInterval:0.01];
}

UIImageView 的“东西”将直接从 20 变为 50。我知道在这种情况下我应该使用 NSTimer,但我只是做了这个例子来保持简单。

那么有没有我可以调用来更新屏幕的函数,某种 VBL?

4

3 回答 3

3

那么有没有我可以调用来更新屏幕的函数,某种 VBL?

不,这不是绘画的工作方式。如果您在一个循环中更改视图 50 次,则运行循环永远不会有机会在更改之间更新显示,因此他的所有更改似乎都是一次发生的。您需要定期使视图无效,并让操作系统调用您的代码以进行每次更改。

这并不难,但有一个更简单的方法:使用 Core Animation。CA 让您说“在 n 秒内平滑地将此视图的中心更改为我的新值”。一旦你开始动画,你就可以忘记它——CA会处理剩下的事情:

[UIView animateWithDuration:3.0 animations:^{something.center = newCenter}];

这会将 的中心移动somethingnewCenter3 秒以上。你可以做很多很多,但你可以自己阅读。

如果要使用计时器,则需要编写一个更新例程,它只执行动画的一个步骤并返回。然后让计时器在每次触发时调用更新例程,以便视图移动一点点。当视图到达目的地时,终止计时器。但是 CA 为您完成了这一切,而且做得更好。

于 2012-08-31T20:39:19.673 回答
1

我认为您不应该在这种情况下使用计时器。当我寻找类似的东西时,我发现 aCADisplayLink更合适。当CADisplayLink屏幕内容更新时,您会收到通知。也就是说,不是在固定的时间间隔内调用方法,而是计算经过的时间并相应地更新您的内容。我已经使用这种机制来实现一个UIScrollView子类,它的内容偏移可以使用其他时间函数而不是线性时间来动画。每次显示链接触发时,我都会相应地设置内容偏移量。请注意,实施可能并不完美,因为它尚未经过深入测试。但是,也有很好的使用教程CADisplayLink

于 2012-09-01T07:05:23.763 回答
0

由于将主线程用于 UI 是最佳实践(如提到的 H2CO3),因此我不建议使用sleepForTimeInterval,因为它阻塞了可以说是最重要工作的线程(至少对用户而言)。相反,您可以使用这样的计时器:

- (void) updatePosition {

    while(something.center.x < 50) {
        something.center = CGPointMake(something.center.x + 1, something.center.y);
    }
}

NSTimer *timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(updatePosition) userInfo:nil repeats:YES];
[timer fire];

当然,您必须调整代码并进行一些修改,但这是您应该做的要点。

于 2012-08-31T20:24:10.453 回答