Создание дыма может быть полезной уловкой, потому что вы можете использовать его для множества применений, например, когда ракета стреляет, когда извергается вулкан или когда автомобиль мчится. Так как же создать дым в Windows Phone 7?
Есть много способов добиться этого эффекта, но в этом посте вы будете использовать рамочный подход для создания дыма. Эффект при воспроизведении на вашем Windows Phone или эмуляторе довольно крутой, как будто дым выходит из телефона!
Понимание физики дыма
Давайте посмотрим на физическое поведение дыма, выходящего из вулкана. Возьмите небольшой образец дыма, как показано ниже в красном прямоугольнике. Вот наблюдаемое поведение дыма:
Поведение дыма | Как обращаться с Windows Phone 7 |
Дым движется вверх со случайной скоростью. | Canvas.Leftproperty и Canvas.TopProperty изменяются случайным образом. |
Когда дым поднимается, он становится больше. | ScaleX и ScaleY дыма меняются случайным образом. |
Дым постепенно исчезает. | Непрозрачность дыма меняется случайным образом. |
Создание дыма на кадр
В основном вам нужно создать крошечное изображение дыма, как показано на рисунке ниже. Каждое изображение дыма будет наблюдать три поведения, описанных в разделе выше. По мере того как кадр будет отображаться, вы будете добавлять дополнительные изображения дыма.
Чтобы добавить дым на кадр, вы будете использовать код ниже в MainPage.xaml:
public MainPage() { InitializeComponent(); CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); } private void CompositionTarget_Rendering(object sender, EventArgs e) { SmokeImage smoke = new SmokeImage(); LayoutRoot.Children.Add(smoke); smoke.X = 200; smoke.Y = 700; }
Описание поведения дыма в коде
Теперь, когда вы добавляете дым в кадр, вам нужно убедиться, что каждый добавленный дым ведет себя так, как описано в коде выше.
Класс SmokeImage унаследует от Canvas, и при визуализации фрейма дым изменит свое собственное свойство.
Свойства дыма
В качестве части свойств дыма вам понадобится изображение дыма (_smoke), генератор случайных чисел (_rnd), скорость для направления x и y (_velocityX и _velocityY) и коэффициент масштабирования непрозрачности (_currentScale). Обратите внимание, что X и Y используются первоначально один раз, когда дым добавляется на родительский холст, и с этой начальной позиции дым начнет свое движение в небо и исчезнет.
private Random _rnd = new Random(); private Image _smoke; // Control the speed of the smoke going up private double _velocityX; private double _velocityY; // dissipates rate of smoke as it rises private double _currentScale; // X and Y is used to position starting location of the smoke public double X { get { return (double)(GetValue(Canvas.LeftProperty)); } set { SetValue(Canvas.LeftProperty, value); } } public double Y { get { return (double)(GetValue(Canvas.TopProperty)); } set { SetValue(Canvas.TopProperty, value); } }
Инициализация Дым
Многое происходит при инициализации, но я хочу отметить две вещи: 1) у вас есть возможность изменить изображение дыма и 2) с помощью CompositionTarget.Rendering, вы будете изменять свойства дыма на кадр. Вот код:
public SmokeImage() { // Set speed of smoke rising random so it is more realistic _velocityX = _rnd.Next(-1, 1) – _rnd.Next(-1, 1); _velocityY = _rnd.Next(-1, 1) * 3 – 5; _smoke = new Image(); _smoke.Width = 40; _smoke.Height = 40; _smoke.Source = new BitmapImage(new Uri(“/SmokeAnimationDemo;component/smoke.png”, UriKind.Relative)); this.Children.Add(_smoke); // create different smokes dark to faded _smoke.Opacity = _rnd.Next(0, 100); // create different size of smoke _currentScale = _rnd.Next(1); ScaleTransform scale = new ScaleTransform(); scale.ScaleX = _currentScale; scale.ScaleY = _currentScale; _smoke.RenderTransform = scale; // set frame rate higher the frame rate more smokes it will create App.Current.Host.Settings.MaxFrameRate = 25; CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); }
Изменение свойств дыма на кадр
Вы будете изменять свойства дыма для каждого кадра, как описано в разделах выше. Одна из самых важных вещей, которую вы должны знать, это то, что, когда непрозрачность дыма становится нулевой, вы должны обязательно удалить изображение дыма из родительского холста. Если вы этого не сделаете, то в конечном итоге вы добавите МНОГО дыма и пожираете память. Смотрите код ниже:
private void CompositionTarget_Rendering(object sender, EventArgs e) { // Smoke fades as it rises _smoke.Opacity -= 1; // Smoke rises up Canvas.SetLeft(_smoke, Canvas.GetLeft(_smoke)+_velocityX); Canvas.SetTop(_smoke, Canvas.GetTop(_smoke)+_velocityY); // Smoke dissipates _currentScale += 0.09; ScaleTransform scale = new ScaleTransform(); scale.ScaleX = _currentScale; scale.ScaleY = _currentScale; _smoke.RenderTransform = scale; // remove smoke if it fades completely if (_smoke.Opacity < 0) { RemoveSelf(); } } private void RemoveSelf() { CompositionTarget.Rendering -= new EventHandler(CompositionTarget_Rendering); ((Canvas)this.Parent).Children.Remove(this); }
Скачать код
Вывод
В этом блоге вы узнали о создании эффекта дыма с использованием рамочного подхода в Windows Phone 7 и познакомились с использованием события CompositionTarget.Rendering для достижения этой цели.
Источник: http://blog.toetapz.com/2010/12/15/create-smoke-using-frame-based-animation-in-windows-phone-7/