Silverlight: Разработка MMORPG. Анимирование объектов (Part 3)
Способ анимации №3. DispatcherTimer
Последним вариантом является DispatcherTimer, он также основан на UI потоке, кадр за кадром, но работает несколько иначе, чем CompositionTarget. Вы наверное помните, что частота кадров в CompositionTarget не контролируемая, но в DispatcherTimer вы можете задать для этого интервал.
Итак мы до сих пор используем неизменный XAML файл, отличия лишь в его code-behind части:
public partial class MainPage : UserControl
{
private Rectangle rect;
//устанавливаем скорость движения
double speed = 5;
double speed_X;
double speed_Y;
//конечная точка
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);
//инициализируем 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);
}
}
Собственно, разница заключается в добавлении четырех строчек кода:
//init DispatcherTimer
DispatcherTimer dispatcherTimer = newDispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50);
dispatcherTimer.Start();
А также я использую dispatcherTimer_Tick вместо метода CompositionTarget_Rendering из предыдущей статьи, но логика работы этих двух функций остается низменной.
Пришло время сравнить все три метода для создания анимации в Silverlight. Прежде всего, многие люди предпочитают технику раскадровки, потому что она легка в понимании и удобна в реализации. Фактически, каждый способ имеет свои области применения. Давайте посмотрим где же можно применять каждый вариант анимации.
Раскадровку удобно использовать для создания простых движений, особенно она мощна в сложных анимациях, особенно при комбинировании с ключевыми кадрами (KeyFrame, о которых мы поговорим следующей главе).
CompositionTarget удобен для постоянного изменения свойств объекта, например, RPG игры, где нам нужно все время изменять положение всех объектов на карте.
DispatcherTimer часто используется для спрайт-анимаций: движение, атака, эффекты магии.
Итого
Первые три главы поведали нам, как пользоваться раскадровкой, CompositionTarget и DispatcherTimer для создания анимации. Они широко используются в различных сценариях.
В следующей главе я расскажу вам, как сделать делать "живые" объекты. Следите за обновлениями.
Демо к данной главе можно загрузить тут
Источник - Jianqiang Bao