在更新循环中实现轻松

时间:2013-03-19 16:40:59

标签: objective-c easing

我想以某种减速方式将精灵从点y1动画到点y2。当它到达点y2时,物体的速度将为0,因此它将完全停止。

我知道这两点,我知道对象的起始速度。 动画时间对我来说并不那么重要。如果需要,我可以决定。

例如:y1 = 0y2 = 400,每秒v0 = 250像素(=起始速度)

我读到了关于缓动函数但我不明白我如何在实际中实现它 更新循环。 这是我的更新循环代码,其中应该以某种方式实现缓动函数。

-(void)onTimerTick{
   double currentTime =  CFAbsoluteTimeGetCurrent() ;
   float timeDelta = self.lastUpdateTime - currentTime;
   self.lastUpdateTime = currentTime;

   float *pixelsToMove = ???? // here needs to be some formula using v0, timeDelta, y2, y1

   sprite.y +=  pixelsToMove;
}

1 个答案:

答案 0 :(得分:6)

定时功能为Bézier曲线

缓和时间函数基本上是从(0,0)(1,1)的贝塞尔曲线,其中水平轴是“时间”而垂直轴是“变化量”。由于Bézier曲线在数学上是

start*(1-t)^3 + c1*t(1-t)^2 + c2*t^2(1-t) + end*t^3 

您可以插入任何时间值并获取应该应用的更改量。请注意,时间和变化都是标准化的(范围为0到1)。

注意,变量t 时间值,t是曲线到达的距离。 时间值是曲线上点的x值


下面的曲线是一个样本“缓和”曲线,它开始变慢,变得更快,最后变慢。

如果例如三分之一的时间已经过去,您将计算相应的更改量,以更新动画属性的值

currentValue = beginValue + amountOfChange*(endValue-beginValue)

Bézier curve for "ease" timing function

实施例

假设您使用控制点位于(50, 50)(200, 150)的曲线以及持续时间为4秒的曲线({1}}为(0.6, 0.0)设置动画的位置(控制点为试图接近上图的那个。)

当动画的1秒过去时(总持续时间的25%),沿着曲线的值是:

(0.5, 0.9)

这意味着我们可以将(0.25,y) = (0,0)*(1-t)^3 + (0.6,0)*t(1-t)^2 + (0.5,0.9)*t^2(1-t) + (1,1)*t^3 计算为:

t

Wolfram Alpha tells me 0.25 = 0.6*t(1-t)^2 + 0.5*t^2(1-t) + t^3

如果我们输入t = 0.482359

t

我们将在1秒的持续时间过后获得“变化量”。

再次Wolfram Alpha tells me y = 0.9*t^2*(1-t) + t^3 表示22%的价值在25%的时间后发生了变化。这是因为曲线开始变慢(您可以在图像中看到它在开始时大部分是平坦的。)

最后:动画1秒进入位置

y = 0.220626

我希望这个例子可以帮助您了解如何使用计时功能。