2012-01-18 51 views
1

我使用NSTimer通過每秒更新其定位點60次來動畫UIView。 UIView的位置根據其角度而變化,所以它總是看起來相對於設備而言... 但是,NSTimer每秒鐘不會觸發精確地爲。它總是有點偏離,造成生澀的動畫。我已經搜索了很多,我對delta時間有一些瞭解,但我不知道如何將其應用於我的情況。UIView德爾塔時間

下面是我使用的移動代碼:

float rotation = 0; 

if (leftSideIsBeingHeldDown) { 
    rotation += (0.05f/rotationFactor); 
} else if (rightSideIsBeingHeldDown) { 
    rotation -= (0.05f/rotationFactor); 
} 
movementX += -sinf(rotation); 
movementY += -cosf(rotation); 

float finalX = 0.0001 * movementX; 
float finalY = 0.0001 * movementY; 

mapView.layer.anchorPoint = CGPointMake(finalX, finalY); 

mapView.transform = CGAffineTransformMakeRotation(rotation); 

有誰知道如何增量時間申請呢?

回答

1

您想要記錄上次旋轉的時間以及時間與現在的時間差,並使用該因子計算可用於調整旋轉和x/y值的因子。

例如:

NSDate now = [NSDate now]; 
timeDiff = now - lastRotateTime; 
factor = timeDiff/expectedTimeDiff; 

x = x + xIncrement * factor; 
y = y + yIncrement * factor; 

angle = angle + angleIncrement * factor; 

有關於遊戲開發論壇,其解釋更詳細許多更好的例子。

3

您可能想要查看CADisplayLink類,它爲您提供了一個與顯示刷新速率相關的計時器。在這種情況下,它應該是一個比NSTimer更好的解決方案。

此外,您需要記住每個「打勾」的時間並計算自上次打勾後應該完成的旋轉或移動。例如(僞代碼):

- (void)displayLinkTick:(id)sender 
{ 
    NSTimeInterval timespan; 
    NSDate *now; 

    now = [NSDate date]; 
    if (myPreviousTick) { 
     timespan = [now timeintervalSinceDate:myPreviousTick]; 
    } else { 
     // The very first tick. 
     timespan = 0; 
    } 

    // Calculate the angle according to the timespan. You need a 
    // value that specifies how many degrees/radians you want to 
    // revolve per second and simply multiply that with the timespan. 
    angle += myRadiansPerSecond * timespan; 
    // You'd do the same with the position. I guess this involves 
    // minor vector math which I don't remember right now and am 
    // too lazy to look up. You need to have a distance per second 
    // which you multiply with the timespan. Together with the 
    // direction vector you can calculate the new position. 

    // At the end, remember when this tick ran. 
    [myPreviousTick release]; 
    myPreviousTick = [now retain]; 
}