3) DispatcherTimer
The last method is DispatcherTimer, it is also an animation base on UI thread, frame by frame, but it is different from CompositionTarget. Maybe you still remember that in CompositionTarget, the frequency is not controlled, but in DispatcherTimer, you can set the interval for it.
We still use the XAML the same as the one in the Chapter 2, the difference is in the code-behind, as follows:
public partial class MainPage : UserControl { private Rectangle rect; //set the moving speed double speed = 5; double speed_X; double speed_Y; //set the moving target Point moveTo; public MainPage() { InitializeComponent(); rect = new Rectangle() { Fill = new SolidColorBrush(Colors.Red), Width = 50, Height = 50, RadiusX = 5, RadiusY = 5 }; Carrier.Children.Add(rect); Canvas.SetLeft(rect, 0); Canvas.SetTop(rect, 0); //init DispatcherTimer DispatcherTimer dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Tick += dispatcherTimer_Tick; dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50); dispatcherTimer.Start(); } void dispatcherTimer_Tick(object sender, EventArgs e) { double rect_X = Canvas.GetLeft(rect); double rect_Y = Canvas.GetTop(rect); if (Math.Abs(rect_X - moveTo.X) > speed_X / 2) Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X)); if (Math.Abs(rect_Y - moveTo.Y) > speed_Y / 2) Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y)); } private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { double rect_X = Canvas.GetLeft(rect); double rect_Y = Canvas.GetTop(rect); moveTo = e.GetPosition(Carrier); double len = Math.Sqrt(Math.Pow(moveTo.X - rect_X, 2) + Math.Pow(moveTo.Y - rect_Y, 2)); speed_X = Math.Abs(speed * (moveTo.X - rect_X) / len); speed_Y = Math.Abs(speed * (moveTo.Y - rect_Y) / len); } }
The only difference is the 4 line code as follows:
//init DispatcherTimer
DispatcherTimer dispatcherTimer = newDispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50);
dispatcherTimer.Start();
And also I use dispatcherTimer_Tick to replace the function CompositionTarget_Rendering in the Chapter 2, but the logic in these 2 function are the same.
Now it is time to compare all these 3 methods to create animation in Silverlight. The first one, Storyboard, yes, most people prefer this technique, because it is easy to understand, and convenient to implement. In fact, every method has its own usage. Let’s discuss them one by one.
Storyboard, is suitable to create simple moving and make property changed, especially, it is powerful in more complex animation combined with the KeyFrame.(I will introduce KeyFrame in the next chapter).
CompositionTarget, is suitable to change the property all the time, for example, in RPG games, we need to change the position of all the objects in the map all the time.
DispatcherTimer, is suitable to use in sprite’s own action, such as the sprite’s moving, attacking and spell magic.
Summary: The first 3 chapters introduce how to use Storyboard, CompositionTarget and DispatcherTimer to create animation. They are widely used in different scenarios.
Next chapter, I will introduce how to make the object itself “alive”. Please focus on it.
Chinese friend, you can also visit this Chinese blog if you feel difficult to read English, http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505333.html, part of my article is base on it.
Demo download: http://silverlightrpg.codeplex.com/releases/view/40978