锁定帧每秒到60fps

时间:2016-01-27 04:25:55

标签: c# winforms gdi frame-rate

我在FPS的Extra Credits中看到了这一集,他们提到你通常应该将fps锁定为30的倍数,因为它与显示器的刷新率相匹配并减少了伪影。我的代码运行速度为60fps,但我仍然在运动中获得了非常微妙的文物。

https://www.youtube.com/watch?v=zL5kOyHWI_E

它在Windows窗体中,所以也许没有什么可以做的。

我的渲染循环如下所示:

private void Render() {
    Update();
    if (RenderDelegate != null)
        RenderDelegate(_renderFunctions);
    var msPause = 1000 / (double)FpsLimit - _gameTime.DeltaTime;
    if (msPause > 0)
        System.Threading.Thread.Sleep((int)msPause);
    _attachedSystem.NextFrame(); // Will call Invalidate();
}

WinForms控件中的实现

protected void FormOnPaint(object sender, PaintEventArgs paintEventArgs) {
    _graphic = paintEventArgs.Graphics;
    _render();
}
void IGameMessages.DrawImage(Image image, Rectangle rect) {
    _graphic.DrawImage(image, rect);
}
void IGameMessages.NextFrame() {
    Control.Invalidate();
}

我猜测通过动态值休眠不是首选方式,因为它可能与显示器刷新率不同1%不同? fps输出摆动在58到63 fps之间(DeltaTime计算可能也有问题)

1 个答案:

答案 0 :(得分:1)

WinForm并不理想。原因是屏幕更新不取决于您的应用程序。 WinForms中没有屏幕中断。

我保留了一个计时器,将一个对象从左向右移动了800像素,类似“ sprite”的对象具有一个起始计数器整数。取决于接过新职位的时间多长。

if(!x.AtEnd) {
    X.DeltaTime = X.Startime-currentTime;
    int x = myStartTime - currentTime;
    x.position = X.DeltaTime % 430; //time was in ms and 430 just a number 

    if (x.postion > x.end) {
        x.position=x.end;
        x.AtEnd=true;
    }
}

它多少取决于它移动的速度和外观的好坏(这也取决于计算机的速度,因为速度较慢的计算机也需要更多时间在其他线程上执行)。使用上面类似的方法,我得到了一个合理的平滑移动对象,虽然不像在游戏中那样平滑,但是它工作得很好,并且里面没有阻塞(延迟)代码(因为我尝试了线程延迟,所以每次移动都花了相等的时间,但是也不顺利,因此屏幕更新太随机了