当我尝试使用 System.Windows.Threading.DispatcherTimer 实例控制 WPF 中的帧速率时遇到问题。
为了尝试 DispatcherTimer 的有效性,我创建了一个简单的 WPF 演示,其中包含一个窗口,其中有一个文本框和一个按钮。单击该按钮时,DispatcherTimer 实例开始根据文本框中的双数字作为时间间隔进行计时,并且 StopWatch 同时启动,计数器变量在每个 DispatcherTimer 计时时增加 1。当 StopWatch.ElaspedMilliSeconds > 1000(超过 1 秒)时,计时器停止计时,秒表也重置,弹出消息框显示计数器的值。
因此,如果我输入 33.3(1000/30),计数器值应该约为 30。但结果是20左右。我请求帮助是否有人可以帮助检查我下面的源代码中似乎有什么问题。提前致谢。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TimerDemo
{
public partial class MainWindow : Window
{
private System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
public MainWindow()
{
InitializeComponent();
double ticks = 0L;
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
int frameCount = 0;
//There is a textbox "txtTicks" which accepts a millisecond value
//And a button "btn", by clicking the button the dispatchertimer &
//stopwatcher are started.
_timer.Tick += (sender, e) =>
{
frameCount++;
System.Diagnostics.Debug.WriteLine(watch.ElapsedMilliseconds);
if (watch.ElapsedMilliseconds > 1000)
{
_timer.Stop();
watch.Reset();
MessageBox.Show(string.Format("Already 1 second! FrameCount: {0}", frameCount));
frameCount = 0;
}
};
this.btn.Click += (sender, e) =>
{
double.TryParse(this.txtTicks.Text, out ticks);
if (ticks != 0.0)
{
_timer.Interval = TimeSpan.FromMilliseconds(ticks);
}
_timer.Start();
watch.Start();
};
}
}
}
运行结果如下(Stackoverflow的菜鸟,还不能上传图片):
https://i.stack.imgur.com/u6W2s.png
由于 WPF(和大多数其他渲染引擎)并不需要相同的时间来渲染每一帧,并且由于不同的计算可以进一步延迟帧之间的间隔,因此您使用CompositionTarget.Rendering
来“计时”渲染间隔,但您仍然可以使用“挂钟”计时器来update定期、严格控制的时间间隔进行比赛。
在优秀的书“游戏编程模式”(在线免费提供)中,您可以找到非常有用的内容游戏循环模式.
在其完整形式中,这就是您将在处理程序中放入的内容CompositionTarget.Rendering
事件(伪代码):
double current = getCurrentTime();
double elapsed = current - previous;
previous = current;
lag += elapsed;
processInput();
while (lag >= MS_PER_UPDATE)
{
update();
lag -= MS_PER_UPDATE;
}
render();
在 C# 中,您可以实现getCurrentTime()
要么通过调用DateTime.Now
或通过使用Stopwatch.Elapsed
, 例如。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)