1

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

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

例如:y1 = 0, y2 = 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;
}
4

1 回答 1

7

时序函数作为贝塞尔曲线

缓动计时函数基本上是一条贝塞尔曲线,(0,0)横轴(1,1)是“时间”,纵轴是“变化量”。由于贝塞尔曲线在数学上是

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)

贝塞尔曲线

例子

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

当动画的 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 告诉t = 0.482359

如果我们t输入

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

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

Wolfram Alpha再次告诉我y = 0.220626这意味着 22% 的值在 25% 的时间后发生了变化。这是因为曲线开始时很慢(您可以在图像中看到它开始时大部分是平坦的)。

所以最后: 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)

我希望这个例子能帮助你理解如何使用计时功能。

于 2013-03-19T17:41:02.213 回答