在.NET / GDI +中制作流畅的动画

时间:2012-10-10 09:04:53

标签: c# .net animation cpu stopwatch

我在GDI +中制作流畅的动画时遇到问题。我从谷歌搜索中了解到的问题是,在多核处理器上,.NET中的时钟滴答存在某种错误。这是我正在做的简化版本:

class Animation
{
  System.Diagnostics.Stopwatch sw = new Stopwatch();
  float AnimationTime = 1000; //time it takes the animation to complete

  public bool IsComplete
  { get { return sw.ElapsedMilliseconds > AnimationTime; } }

  public void StartAnimation()
  {
     sw.Reset();
     sw.Start();
  }

  public void DoFrame()
  {
     float PercentComplete = (float)sw.ElapsedMilliseconds / AnimationTime;
     //draw the animation based on PercentComplete
  }
}

DoFrame()的调用如下:

Animation.Start();
do
{
  Animation.DoFrame();
  Application.DoEvents();
} while (!Animation.IsComplete);

问题是动画非常平滑大约15帧然后它猛然,它实际上是向后的(sw.ElapsedMilliseconds给出的值比前一个查询的值小)。它非常烦人,它破坏了我的平滑动画,即使在Core 2 Duo上看起来也很棒(尽管微软称这是一个多核错误)。我有一个i7,动画很流畅,除了每秒2-3帧看起来“生涩”。

我知道这是一个已知问题,微软将其归咎于处理器,所以我的问题是,有没有人知道任何类型的解决方案?我尝试使用卡尔曼滤波器,它有点工作。我希望也许有一个确定的“正确”的解决方案吗?

哦b.t.w。我尝试使用DateTime而不是秒表,并得到了相同的结果。

我也尝试过:

double PercentComplete = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency * 1000 / AnimationTime

它给了我相同的结果。

1 个答案:

答案 0 :(得分:1)

这可能与你致电DoFrame()的方式有关。使用以下基于窗体/基于GDI +的算法,你应该总是得到非常流畅的动画:

const double desiredFps = 500.0;
long ticks1 = 0;
var interval = Stopwatch.Frequency / desiredFps;
while (true)
{
    Application.DoEvents();
    var ticks2 = Stopwatch.GetTimestamp();
    if (ticks2 >= ticks1 + interval)
    {
        ticks1 = Stopwatch.GetTimestamp();

        // do the drawing here
    }
}