
Timing in OpenTK
Posted Tuesday, 31 July, 2012 - 13:49 by Frank Lioty inHi everybody,
I need to implement a timing system to move a texture pixel per pixel on my screen. Firstly I used the OnUpdateFrame() in this way:
protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); //new position if (sprite.moving) { Change_Sprite_Position(sprite, position); } }
it works but I can't make a move faster than 0.03s (because I'm running the application at 30 fps). So I was looking for another way and I'm trying to use a System.Diagnostics.StopWatch.
private void Sprite_Move(Sprite sprite, List<Point> path) { track.Clear(); for (int i = 1; i < path.Count; i++) { //memorize all track pixel, so I can update pixel per pixel my sprite position Bresenham2(path[i-1], path[i]); } //moving flag sprite.moving = true; //start my StopWatch timer.Start(); Loop(timer, sprite); } private void Loop(Stopwatch timer, Sprite sprite) { int i = 1; while (timer.IsRunning) { //moving each 0.03s? if ((sprite.moving) & (timer.Elapsed.Milliseconds >= 30)) { if (i < track.Count) { //change sprite position to the i-th track pixel Sprite_Position(skinny, track[i]); i++; timer.Reset(); Console.WriteLine("Tick"); } //if I'm on the end of the track I can exit else timer.Stop(); } } }
I can't see my sprite moving. Everything is blocked until the last iteration, then I see my sprite on the last pixel of the track...teleport!


Comments
Re: Timing in OpenTK
What do you expect to happen? If you call the
while (timer.IsRunning)loop, it will of course not leave the loop and the function until it's finished, meaning that your main rendering loop stalls and the rendering function is not called until the sprite has stopped moving. When implementing some kind of movement, you have to keep in mind that you are already inside a loop (the main rendering loop) that needs to run for something to be displayed.The correct way to move your sprite is to move it framerate-independently in your rendering function. If you use the GameWindow, that's
void RenderFrame(FrameEventArgs e). Framerate-independent movement means that it does not depend on the framerate of the rendering or update loop, but on time itself, meaning that the movement of your texture for example will take exactly one second on each a high-end system and a wired potato.Use the time span since the last render call,
e.Time, to calculate the incremental update of your movement. Store the total elapsed time, e.g.elapsedTime += e.Time;and use the total elapsed time to calculate your progress:progress = elapsedTime / desiredDurationOfTextureMovement;. Now move your texture to the position where it would be according toprogressand render it once.You can also do this in the UpdateEvent as you already tried, however the update loop usually runs with a limited framerate (30 fps) and the movement can therefore be a bit bumpy, while the rendering loop should run with at least 60 fps.
Re: Timing in OpenTK
thanks a lot, it was really simple at the end :)