DispatcherTimer dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal);
dispatcherTimer.Tick += new EventHandler(Timer_Tick);
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50);
dispatcherTimer.Start();
第一句申明一个界面计时器DispatcherTimer ,并且设置其线程优先级别为Normal,这是标准设置,你可以根据你自己的需求进行更改,一共10个级别。
第二句注册Tick 事件,也就是计时器间隔触发的事件。
第三句设置Tick 事件的间隔,可以有很多方式,我使用的是TimeSpan.FromMilliseconds(),即间隔单位为毫秒。
第四句启动线程。
是不是很简单?这样的话可以很轻松的通过Interval 来控制刷新一个对象属性的频率了。接下来我们同样使用Ctrl+F5来测试一下成果。呵呵,结果和第二种动画方法是一样的,存在同样的问题,因为毕竟两种动画的原理是一致的。
那么到此,三种动态创建动画的方法都已经详细介绍过了,大家可能会有种感觉,比较钟情于第一种WPF/Silverlight推荐的Storyboard动画,既直观又方便使用,而且仿佛不易出错。其实这3种动画都有它特定的使用场合。
第一种动画适合创建简单的对象位移及直接性质的属性更改(在后面的教程中,我还将更深入的挖掘Storyboard动画的潜力,动态创建更复杂的基于KeyFrame的关键帧动画)。
第二种动画适合全局属性的时时更改,例如我们后面要讲到的敌人或NPC以及地图等全体性的相对位移及属性更改时就要用到它了。
第三种动画则非常适合运用在Spirit(角色)的个人动画中,例如角色的移动,战斗,施法等动作。
小结:前三节分别讲解了Storyboard动画,CompositionTarget动画,DispatcherTimer动画,并横向分析了不同的场合对应不同的动画应用模式,这些将是构成WPF/Silverlight游戏引擎的基础。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; namespace WPFApplication { /// <summary> /// chap03.xaml 的交互逻辑 /// </summary> public partial class chap03 : Window { public chap03() { InitializeComponent(); DrawPentacle(); } private void DrawPentacle() { pentacle = new Polygon(); pentacle.Fill = new SolidColorBrush(Colors.Red); pentacle.Opacity = 0.6; PointCollection pointCollection = new PointCollection(); pointCollection.Add(new Point(0, 0)); pointCollection.Add(new Point(40, 0)); pointCollection.Add(new Point(20, 40)); pentacle.Points = pointCollection; Canvas.SetLeft(pentacle, 400); Canvas.SetTop(pentacle, 300); container.Children.Add(pentacle); // DispatcherTimer dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal); dispatcherTimer.Tick += new EventHandler(TimerTick); dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50); //重复间隔 dispatcherTimer.Start(); } private void TimerTick(object sender, EventArgs e) { double pentacleX = Canvas.GetLeft(pentacle); double pentacleY = Canvas.GetTop(pentacle); Canvas.SetLeft(pentacle, (moveTo.X > pentacleX) ? (pentacleX + speed) : (pentacleX - speed)); Canvas.SetTop(pentacle, (moveTo.Y > pentacleY) ? (pentacleY + speed) : (pentacleY - speed)); } private void container_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { moveTo = e.GetPosition(container); } private Polygon pentacle; private int speed = 5; private Point moveTo; } }