I've made a game in GDI and I want to make a fps counter. To do this I use 开发者_StackOverflow中文版a System.Windows.Forms.Timer
with an interval of 1000ms. In the Form1_Paint()
I increment the fps
variable, I draw a text showing the fps and call the this.Invalidate()
at the end. In the Timer_Tick()
I put fps = 0
. In the Form1_Load()
I enable the timer and start it. But the timer doesn't start and the fps
variable doesn't come back to 0. Why the timer doesn't start?
I think the problem is from the this.Invalidate()
, I think that it doesn't let the timer to call the Timer_Tick()
. How can I make the timer call it if this is the problem?
System.Windows.Forms.Timer
is a synchronous timer. It's running on the same thread like the GUI, which means that if the GUI is busy with some heavy logic/calculations, the Timer
won't run.
You're most likely looking for an asynchronous Timer
, which runs on it's own thread, like System.Timers.Timer
and System.Threading.Timer
. But watch-out for cross-thread-calls.
Use a System.Diagnostics.Stopwatch to measure the time between paints. Then calculate the frame rate with ((double)1 / Stopwatch.ElapsedMilliseconds) * 1000. From ElapsedMilliseconds we get "milliseconds per frame", inverting the number gives us "frames per milliseconds" and finally multiplying with 1000 we get the sought after frames per second.
private void Form1_Paint(object sender, PaintEventArgs e)
{
long msec = watch.ElapsedMilliseconds;
watch.Reset();
watch.Start();
label1.Text = ((1d / msec) * 1000).ToString("F") + " FPS";
}
First you'll want to make sure that the timer is actually working. I suspect that it is, but you'll have to write some debugging code to find out for sure. One way is to put a label on your form and have the timer update the label with a tick count (i.e. increments the count each time the timer fires). If the timer is working, then that label should update once per second (approximately).
For your FPS counter, I would suggest that rather than having the timer update the UI, it should just compute the FPS and let the normal game update logic display the FPS when you want it. That way you're not updating the display in multiple places, and you're not wasting time updating the screen just to show the FPS.
精彩评论