First of all, I don't know what timer do you use. If you are using you are using
System.Windows.Forms.Timer
, don't do it: this timer is absolutely unsuitable for animation, because its accuracy is unacceptable, it can be amazingly bad. The only "benefit" of this timer class is the simplicity of its use: it does not require UI thread invocation.
Now, don' rely at exact time of the timer event at all, even with a better timer. Instead, measure "real" time immediately before rendering coordinates. Use
System.Diagnostics.Stopwatch
:
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx[
^].
Calculate your coordinate based on measured time. In this case, even if the time intervals between "frames" are uneven, your motion will be smooth.
Better yet, don't use timers at all. Use additional thread with a cycle and
System.Threading.Thread.Sleep
calls inside a cycle, to setup some frame frequency. As you now will be measuring time in each frame anyway, exact timing does not matter much, but using a thread is way simpler.
Now, you will face the same problem with timers and thread: cross-thread calls to UI, so you have to solve it anyway. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method
Invoke
or
BeginInvoke
of
System.Windows.Threading.Dispatcher
(for both Forms or WPF) or
System.Windows.Forms.Control
(Forms only).
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[
^],
Problem with Treeview Scanner And MD5[
^].
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[
^],
Control events not firing after enable disable + multithreading[
^].
Another important thing is to avoid
flicker. For this purpose, you should use
double buffering. You did not tag you UI library, but you can easily find how to do it in documentation.
—SA