我正在尝试使用CAAnimation.CurrentMediaTime更改显式iOS动画的速度(因此请考虑CABasicAnimation或CAKeyFrameAnimation)。这种方法比停止动画要好得多,然后用新的持续时间重新启动动画。我很接近使这一切都工作,但我有一个小问题。我有时可以启动,暂停,恢复和更改速度,但更改速度功能有问题。任何人都可以了解情况吗?我有一些非常简单的代码和下面的示例项目。
班级变量
UIView MyImage;
double timeSincePause = 0;
double pauseTime = 0;
我的暂停功能(有效)
MyImage.Layer.Speed = 0.0f;
MyImage.Layer.TimeOffset = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - timeSincePause;
我的停止功能(有效)
pauseTime = MyImage.Layer.TimeOffset;
MyImage.Layer.Speed = 1.0f;
MyImage.Layer.TimeOffset = 0.0f;
MyImage.Layer.BeginTime = 0.0f;
timeSincePause = (MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - pauseTime);
MyImage.Layer.BeginTime = timeSincePause;
我的更改速度功能(不起作用)要重现问题,只需启动项目并按几次更改速度按钮即可。请注意,当速度从100%变为30%时,它会正确地改变速度,但是当它从30%速度变为100%速度时,物体的位置会向前跳跃,就像速度从未变为30%一样。这显然是我正在保存的时间值的一个问题,我已经进行了实验并且无法使其工作。
MyImage.Layer.TimeOffset = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer);
MyImage.Layer.BeginTime = CAAnimation.CurrentMediaTime();
// I have it set so the speed changes back and forth between 100% and 30%.
if ( MyImage.Layer.Speed == 1.0f )
MyImage.Layer.Speed = 0.3f;
else
MyImage.Layer.Speed = 1.0f;
以下链接指向非常简单的示例项目写入 C#with Xamarin Studio iOS :https://www.dropbox.com/s/ndfo12rbemsnp1s/ChangeAnimationSpeed.zip
---------附加信息----------
我已经确定问题是我不考虑因速度变化导致的时间损失/获得...我只是不确定如何将其考虑在内......所以我基本上需要添加另一个名为“totalTimeLostResultingFromSpeedChange”的类级别变量,并以某种方式跟踪它和因素...
答案 0 :(得分:3)
我终于开了几天后终于解决了这个问题!这是C#Xamarin iOS project。以下是关键功能。对于没有使用游戏引擎在iOS中制作动画的人来说,这是一些有价值的东西。
班级变量
UIView MyImage;
double currentPauseTime = 0;
double totalPauseTime = 0;
double currentChangeSpeedTime = 0;
double currentTimeLostResultingFromSpeedChange = 0;
double totalTimeLostResultingFromSpeedChange = 0;
float currentSpeed = 0;
关键功能
public void PauseAnimation()
{
if ( MyImage.Layer.Speed != 0.0f )
{
Update_TotalTimeLostResultingFromSpeedChange();
MyImage.Layer.Speed = 0.0f;
MyImage.Layer.TimeOffset = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - totalPauseTime - totalTimeLostResultingFromSpeedChange;
currentPauseTime = MyImage.Layer.TimeOffset;
}
}
public void ResumeAnimation()
{
if ( MyImage.Layer.Speed == 0.0f )
{
MyImage.Layer.Speed = 1.0f;
MyImage.Layer.TimeOffset = 0.0f;
MyImage.Layer.BeginTime = 0.0f;
// Because we reset the BeginTime and TimeOffset, Reset the totalTimeLostResultingFromSpeedChange
Reset_TotalTimeLostResultingFromSpeedChange();
totalPauseTime = (MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - currentPauseTime);
MyImage.Layer.BeginTime = totalPauseTime;
}
ChangeAnimationSpeed( currentSpeed );
}
public void ChangeAnimationSpeed( float speed )
{
if ( speed != 0.0f )
{
Update_TotalTimeLostResultingFromSpeedChange();
currentChangeSpeedTime = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer);
MyImage.Layer.TimeOffset = currentChangeSpeedTime - totalPauseTime - totalTimeLostResultingFromSpeedChange;
MyImage.Layer.BeginTime = CAAnimation.CurrentMediaTime();
currentSpeed = speed;
MyImage.Layer.Speed = currentSpeed;
}
}
public void Update_TotalTimeLostResultingFromSpeedChange()
{
double value = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - currentChangeSpeedTime;
currentTimeLostResultingFromSpeedChange = value - (value * MyImage.Layer.Speed);
totalTimeLostResultingFromSpeedChange += currentTimeLostResultingFromSpeedChange;
}
public void Reset_TotalTimeLostResultingFromSpeedChange()
{
totalTimeLostResultingFromSpeedChange = 0;
}