C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(二)让物体动起来②
2009-06-25 16:57
447 查看
第二种方法,CompositionTarget动画,官方描述为:CompositionTarget对象可以根据每个帧回调来创建自定义动画。其实直接点,CompositionTarget创建的动画是基于每次界面刷新后触发的,与窗体刷新率保持一致,所以频率是固定的,很难人工介入控制。
那么如何使用它?xaml的界面代码还是和上一篇中描述的一样,这里不累述了。那么接下来就是创建对象并注册事件,全部代码如下:
CompositionTarget的注册事件方法为:
因为我们要实现的是鼠标点哪方块就移动到哪,所以我用一个变量moveTo保存鼠标点击点的Point。并在鼠标左键事件中赋值:moveTo = e.GetPosition(Carrier);同时设置方块X,Y方向的速度均为speed。
接下来就是实现Timer_Tick了,它是基于窗体的时时刷新事件。我们这样写:
首先获取方块的X,Y位置,接下让方块的X,Y与moveTo的X,Y进行比较而判断是+speed还是-speed,这里的逻辑需要朋友们自行领会了。
好了Ctrl+F5测试一下,呵呵,是不是同样也动起来了呢?
可是大家会发现一个很大的问题:这方块移动得也太勉强了吧,抖来抖去的而且移动得也不平滑,是不是CompositionTarget有问题?其实不然,因为之前的Storyboard动画它不存在X,Y轴的速度,只需要设定起点和终点以及过程经历的时间就可以平滑的移动了,而CompositionTarget需要分别设定X,Y轴的速度,而我们这为了简单演示,X,Y轴的速度speed均设置成了5,这在现实使用中是绝对不合理的。因此,如果要模拟实际效果,必须计算终点和起点的正切值Tan,然后再根据直线速度speed通过Tan值计算出speed_X,speed_Y,最后改写成:
这样才能实现真实的移动(具体算法就不讨论了)。
这一节讲解了如何使用CompositionTarget主界面刷新线程实现基于帧的动画,下一节我将讲解第三种动态创建动画的方法,并会对这三种方法进行一个归纳比较。
那么如何使用它?xaml的界面代码还是和上一篇中描述的一样,这里不累述了。那么接下来就是创建对象并注册事件,全部代码如下:
Rectangle rect; //创建一个方块作为演示对象 double speed = 1; //设置移动速度 Point moveTo; //设置移动目标 public Window1() { InitializeComponent(); rect = new Rectangle(); rect.Fill = new SolidColorBrush(Colors.Red); rect.Width = 50; rect.Height = 50; rect.RadiusX = 5; rect.RadiusY = 5; Carrier.Children.Add(rect); Canvas.SetLeft(rect, 0); Canvas.SetTop(rect, 0); //注册界面刷新事件 CompositionTarget.Rendering += new EventHandler(Timer_Tick); } private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { moveTo = e.GetPosition(Carrier); }
CompositionTarget的注册事件方法为:
CompositionTarget.Rendering += new EventHandler(Timer_Tick);
因为我们要实现的是鼠标点哪方块就移动到哪,所以我用一个变量moveTo保存鼠标点击点的Point。并在鼠标左键事件中赋值:moveTo = e.GetPosition(Carrier);同时设置方块X,Y方向的速度均为speed。
接下来就是实现Timer_Tick了,它是基于窗体的时时刷新事件。我们这样写:
private void Timer_Tick(object sender, EventArgs e) { double rect_X = Canvas.GetLeft(rect); double rect_Y = Canvas.GetTop(rect); Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed : -speed)); Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed : -speed)); }
首先获取方块的X,Y位置,接下让方块的X,Y与moveTo的X,Y进行比较而判断是+speed还是-speed,这里的逻辑需要朋友们自行领会了。
好了Ctrl+F5测试一下,呵呵,是不是同样也动起来了呢?
可是大家会发现一个很大的问题:这方块移动得也太勉强了吧,抖来抖去的而且移动得也不平滑,是不是CompositionTarget有问题?其实不然,因为之前的Storyboard动画它不存在X,Y轴的速度,只需要设定起点和终点以及过程经历的时间就可以平滑的移动了,而CompositionTarget需要分别设定X,Y轴的速度,而我们这为了简单演示,X,Y轴的速度speed均设置成了5,这在现实使用中是绝对不合理的。因此,如果要模拟实际效果,必须计算终点和起点的正切值Tan,然后再根据直线速度speed通过Tan值计算出speed_X,speed_Y,最后改写成:
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X)); Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y));
这样才能实现真实的移动(具体算法就不讨论了)。
这一节讲解了如何使用CompositionTarget主界面刷新线程实现基于帧的动画,下一节我将讲解第三种动态创建动画的方法,并会对这三种方法进行一个归纳比较。
相关文章推荐
- C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(一)让物体动起来①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三)让物体动起来③
- C#开发WPF/Silverlight动画及游戏系列教程(2)让物体动起来
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三)让物体动起来③
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三)让物体动起来③
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(四)实现2D人物动画①
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):目录
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十八) 完美精灵之八面玲珑(WPF Only)②
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十九) 完美精灵之八面玲珑(WPF Only)③
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十) 第一部分拓展小结篇
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十三) 锦上添花之魔法特效装饰
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十一)主位式地图移动模式