我倾向于使用 CADisplayLink 来触发新帧,并在帧请求中进行简单的时间计算,以确定我的逻辑可以推进多远。
假设您有一个 NSTimeInterval 类型的成员变量 timeOfLastDraw。你希望你的逻辑以每秒 60 次的速度打勾。然后(使用一大堆变量使代码更清晰):
- (void)displayLinkDidTick
{
// get the time now
NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate];
// work out how many quantums (rounded down to the nearest integer) of
// time have elapsed since last we drew
NSTimeInterval timeSinceLastDraw = timeNow - timeOfLastDraw;
NSTimeInterval desiredBeatsPerSecond = 60.0;
NSTimeInterval desiredTimeInterval = 1.0 / desiredBeatsPerSecond;
NSUInteger numberOfTicks = (NSUInteger)(timeSinceLastDraw / desiredTimeInterval);
if(numberOfTicks > 8)
{
// if we're more than 8 ticks behind then just do 8 and catch up
// instantly to the correct time
numberOfTicks = 8;
timeOfLastDraw = timeNow;
}
else
{
// otherwise, advance timeOfLastDraw according to the number of quantums
// we're about to apply. Don't update it all the way to now, or we'll lose
// part quantums
timeOfLastDraw += numberOfTicks * desiredTimeInterval;
}
// do the number of updates
while(numberOfTicks--)
[self updateLogic];
// and draw
[self draw];
}
在您的情况下, updateLogic 将应用固定数量的旋转。如果你真的想要恒定旋转,那么你可以将旋转常数乘以 numberOfTicks,或者甚至跳过整个方法并执行以下操作:
glRotatef([NSDate timeIntervalSinceReferenceData] * rotationsPerSecond, 0, 0, 1);
而不是保留自己的变量。但是,除了最微不足道的情况外,您通常希望在每个时间量子上做一大堆复杂的事情。