views:

627

answers:

2

I have tried translating (moving) a canvas but I'm having trouble with the timers.

I tried 2 different methods:

First method was with the BeginAnimation function, and the second with DispatcherTimer ticks, but they're both very unreliable.

I need to monitor every step of the translation. With the first method I tried (BeginAnimation), I did the Collision Detection logic in the Changed event, and with the second method (DispatcherTimer) I am doing the Collision Detection logic in the Tick event of the timer.

The problem is that both are very unreliable. In the sense that, in my collision detection logic, the canvas should stop translating when its TranslateTransform's Y property is <= 0 (technically, if it is monitoring every step, it should stop at 0 every time) , but with both methods I tried, it varies when it stops. For example, sometimes it stops at 0, sometimes at -1, -2, -3 and sometimes even at -4.

So what's with the discrepancies ? Why doesn't it monitor every step of the way like it's supposed to ?

What can I do to animate this canvas and really monitor every step of the way? An I mean every step...every pixel it moves

A: 

You should hook into the CompositionTarget.Rendering event.

When you hook into this event it gets fired every time a frame is about to be rendered frame and hence you can move your sprites according to how much time has elapsed since the last event call. Once your sprites have stopped moving you need to unhook from the event as WPF will render frames as fast as it can as long as there are any events hooked into the event.

For more info about the event and how to use it try this blog entry that goes into more details and has code you can download to examine.

Phil Wright
+2  A: 

Your problem is that everything is time based, you don't get a callback every time the canvas moves one pixel, you get a callback every time a frame is rendered - and the system doesn't even try to hard to render the frames at a constant rate.

The end result is what you are seeing, sometimes you can get a callback after a 1/2 pixel move because everything went smoothly, the next time it's two pixels move because the GC kicked in mid-frame and the time after that it's a 4 pixels move because Word running in the background stole some CPU cycles to run the spell chekcer.

This is how those things work, you can either deal with it and set a higher tolerance for you collision detection or you can run your simulations off screen on a "virtual timeline" where you can advance objects at whatever pace you want without considering the realities of on-screen animations.

I wrote software that does simulation and collision detection for real aircrafts - and I can tell you it took a lot of hard work, any framework built for animations is optimized for moving things on-screen not for all the work you have to do for high quality simulations and defiantly not for accurate collision detection.

Nir