How I make a timer?
In VB.NET (not sure about c#)
Private oStopWatch As Stopwatch = New Stopwatch()
Private Sub ctlSketch_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler Application.Idle, AddressOf Me.Application_Idle
Private Sub Application_Idle(ByVal sender As Object, ByVal e As EventArgs)
Me.oStopWatch.Stop() ' We've measured everything since last Idle run
Dim dMilliseconds As Double = Me.oStopWatch.Elapsed.TotalMilliseconds
Me.oStopWatch.Reset() ' Reset stopwatch
Me.oStopWatch.Start() ' Restart stopwatch
There are two main approaches to timers:
First, you need to decide what kind of accuracy you need:
Use a Stopwatch for accurate measurements over a few seconds. Use DateTime.Now as a wall clock (for example, to measure total gameplay time). Use Threading.Timer to schedule an event to be fired in the future (just take care that the event is fired in a new thread, so don't write OpenGL code directly inside the handler).
CheatCat: what is it that you want to do?
Am I right in thinking Stopwatch is syncronous and Timer calls an asyncronous thread aswell? Or can stopwatch be used to invoke a separate thread on a delegate?
Stopwatch is synchronous, no threads involved AFAIK.
Timer is used in WinForms development to trigger a continous flow of events. It has no precision whatsoever, think 10th of a second. Over time it lags too; if you set it to trigger an event once a second it will be off-beat in a minute if your OS is doing anything fun in the background.
Again; what is it that you are trying to do in your application? My guess is that you are doing animation of the player jumping (reading other threads).
If I'm right, you can use GameWindows built-in delta-time measurements. In UpdateFrame(double deltaTime) deltaTime is a measure of how long time has passed since the last call to UpdateFrame(). I'll leave the details to you (don't know them by heart).
The 2.0 BCL provides three event-based and two polling-based timer implementations.
Verdict: use System.Threading.Timer, unless you need more features (in that case, check out System.Timers.Timer). Avoid System.Windows.Forms.Timer, unless you are writing a GUI application.
Verdict: use Stopwatch if you need sub-second precision; use DateTime.Now otherwise.
You can use "e.Time" in GameWindow.UpdateFrame and RenderFrame to get the elapsed period since the last UpdateFrame/RenderFrame event respectively. This is based on Stopwatch, hence accurate, but don't use it to measure large time spans.
If I recall correctly, CheatCat wanted a timer to control animation. Solution: use e.Time from UpdateFrame event:
protected override void UpdateFrame(FrameEventArgs e)
// Simple jump calculation
Player.Velocity = new Vector(0, 20, 0); // 20 m / s, direction: up
// Simple movement calculation. Can get numerically unstable over time,
// though it's generally not a problem in practice.
Player.Velocity += Gravity * e.Time; // Gravity is defined as Vector(0, -10, 0) m / s^2
Player.Position += Player.Velocity * e.Time;
By playing around with the values, you can get nice results with very little work.
I would avoid using DateTime.Now. I recall profiling a while back and noticing that DateTime.Now seems to box some ints, so several calls to it in each frame can generate quite a bit of garbage.
Site design by Stefanos A. Icons courtesy of gnome-colors.