2013-03-19 27 views
0

我想从点y1到点y2以某种形式的减速来动画一个精灵。当它到达点y2时,物体的速度将为0,因此它将完全停止。在更新循环中实现更容易

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

例如:每秒y1 = 0y2 = 400v0 = 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; 
} 
+0

为什么,为什么,你为什么不使用Core Animation?为什么重新发明轮子? – 2013-03-19 16:43:27

+0

因为,因为我在此更新循环中执行其他操作和验证。 – 2013-03-19 16:50:13

+0

我不知道这是否是一个有效的论证,或者我只是想解释Bézier曲线:D – 2013-03-19 18:39:54

回答

6

定时用作贝塞尔曲线

缓动定时功能基本上是一个贝塞尔曲线从(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

变化假设您使用控制点为(0.6, 0.0)(0.5, 0.9)且持续时间为4秒的曲线将动画的位置从(50, 50)设置为(200, 150) (控制点试图接近上面的图像)。

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

(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为:

0.25 = 0.6*t(1-t)^2 + 0.5*t^2(1-t) + t^3 

Wolfram Alpha tells met = 0.482359

如果我们输入t

y = 0.9*t^2*(1-t) + t^3 

当持续1秒时间内,我们将获得“变化量”。

再次Wolfram Alpha tells mey = 0.220626这意味着在25%的时间后值的22%已经改变。这是因为曲线开始较慢(您可以在图像中看到它在开始时基本平坦)。

所以最后1秒到动画中的位置是

(x, y) = (50, 50) + 0.220626 * (200-50, 150-50) 
(x, y) = (50, 50) + 0.220626 * (150, 100) 
(x, y) = (50, 50) + (33.0939, 22.0626) 
(x, y) = (50+33.0939, 50+22.0626) 
(x, y) = (83.0939, 72.0626) 

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

+0

感谢您的详细解释:)我现在理解这个概念,但实际上 - 我需要计算“变化量”使用贝塞尔点(c1,c2)和经过时间(x)。为此,我需要用包含c1,c2,x的表达式替换't'变量。我无法弄清楚如何去做,因为这是一个复杂的等式。 – 2013-03-20 13:37:09

+0

这就是为什么我强烈建议让Core Animation来处理它。如果事先知道控制点,则可以计算t = f(x)并且它不会太难。如果您需要在运行时更改c1和c2,您仍然可以[通过将所有常量更改为变量]获得[WolframAlpha的一些帮助](http://www.wolframalpha.com/input/?i=c+%3D+a*t% 281-t%29%5E2 +%2B + b * t%5E2%281 -t%29 +%2B + t%5E3)但这并不容易 – 2013-03-20 15:39:22

+0

我不确定我明白't'是什么在你的公式中。不过,我成功实现了如下这些缓解功能:http://www.gizma.com/easing/。他们返回我需要的价值。但正如我在开球时所写的那样,我想控制起跑速度,所以我需要手动调整持续时间以获得所需的起跑速度。还是有另一种方式? – 2013-03-20 16:39:37