我正在使用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吗?
答案 0 :(得分:3)
那么有一个函数我可以调用来更新屏幕,某种VBL吗?
没有。这不是绘画的工作方式。如果在循环中将视图更改50次,则运行循环永远不会有机会在更改之间更新显示,因此所有更改似乎都立即发生。您需要定期使视图无效,并让操作系统调用您的代码进行每次更改。
这并不难,但还有一种更简单的方法:使用Core Animation。 CA允许您说“在n秒内平稳地将此视图的中心更改为我的新值”。一旦你开始动画,你就可以忘掉它 - CA负责其余的事情:
[UIView animateWithDuration:3.0 animations:^{something.center = newCenter}];
这会将something
的中心移动到newCenter
超过3秒。你可以做更多,但更多,但你可以自己阅读。
如果你想使用一个计时器,你需要编写一个更新例程,它只会动画一个步骤并返回。然后让计时器在每次触发时调用更新例程,以便稍微移动视图。当视图到达目的地时,请终止计时器。但是CA会为你做这一切,并且做得更好。
答案 1 :(得分:1)
我认为你不应该在这种情况下使用计时器。当我寻找类似的东西时,我发现CADisplayLink
更合适。通过使用CADisplayLink
,您可以在屏幕内容更新时获得通知。也就是说,不是在固定的时间间隔内调用方法,而是计算通过的时间并相应地更新内容。我已经使用这种机制来实现UIScrollView
subclass,其内容偏移可以使用除线性时序之外的其他时序函数来动画。每次显示链接触发时,我都会相应地设置内容偏移量。请注意,实施可能并不完美,因为它没有经过严格测试。但是,还有一个关于使用CADisplayLink
的好教程。
答案 2 :(得分: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];
当然,您必须调整代码并进行一些修改,但这是您应该做的事情的要点。