我在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给出的值比之前的查询要小)。这是非常恼人的,它破坏了我的其他流畅的动画,即使在Core2 Duo上看起来也很棒(尽管微软说这是一个多核bug)。我有一个i7和动画是平滑的,除了2-3帧每秒看起来“肉干”。
我知道这是一个已知的问题,微软将其归咎于处理器,所以我的问题是,有人知道解决这个问题的方法吗?我试着使用卡尔曼滤波器,它是一种工作。我希望也许有一个既定的“正确”的解决方案?
哦,b.t.w.我试着用DateTime代替秒表,得到了同样的结果。
我也试过了:
double PercentComplete = (double)sw.ElapsedTicks / (double)Stopwatch.Frequency * 1000 / AnimationTime它给了我相同的结果。
发布于 2012-10-10 17:51:55
这可能与您调用DoFrame()的方式有关。使用以下基于windows forms / 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
}
}https://stackoverflow.com/questions/12815701
复制相似问题