WPF弹性模拟动画-阿里云开发者社区

开发者社区> 老朱教授> 正文

WPF弹性模拟动画

简介:
+关注继续查看

我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的。


胡克定律:F=-kd


F代表弹性力的大小
d
是拉伸的位移
k
为弹性系数
在我们的动画中还将加入摩擦力,否则物体就如在真空中运动,永远不会停止。

需声明的是,以上知识并不属于我,也不是来自课本,要知道我的初中物理及格次数并不多,这些是来自于奇才Robert Penner的著作,而以下示例也是其书中Flash示例的翻版。

下面开始我们的示例:

首先我在Expression Design中设计了一个球的外观以及一个渐变的背景:

然后将它们导出为WPF资源字典,在Visual Studio中新建一个项目,引用上述资源做Ellipse元素和Window元素的背景,创建如下的界面:

需注意的是,要将两个SliderMaximum属性设为1LargeChange属性设为0.1,因为我们的两个属性取值范围都是在0-1之间。

在后台代码中将窗体的DataContext属性设为其自身,即“this”。
然后实现INotifyPropertyChanged接口,并设置4个用于前台绑定的4个属性:XY、弹性系数、流体摩擦力
之后将EllipseCanvas.TopCanvas.Left属性分别绑定到YX,两个SliderValue属性分别绑定到弹性系数和流体摩擦力。

之后为Window增加ContentRendered事件处理,在此将初始化一个计时器,以此来控制动画的每个帧:

DispatcherTimer 帧计时器;

 

private void Window_ContentRendered(object sender, EventArgs e)

{

    帧计时器 = new DispatcherTimer();

    帧计时器.Tick += new EventHandler(帧计时器_Tick);

    帧计时器.Interval = TimeSpan.FromMilliseconds(10);

    帧计时器.Start();

}

 

double x = 0;

double y = 0;

 

void 帧计时器_Tick(object sender, EventArgs e)

{

    var X轴弹力 = (X - 目标位置.X) * -弹性系数;

    x += X轴弹力;

    x *= 1-流体摩擦力;

    X += x;

    var Y轴弹力 = (Y - 目标位置.Y) * -弹性系数;

    y += Y轴弹力;

    y *= 1 - 流体摩擦力;

    Y += y;

}

计时器每次触发时,都将进行位置计算,并调整XY的值。

其中的目标位置是在鼠标单击时指定的,为此还要为Window增加PreviewMouseLeftButtonDown事件处理:

private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

    var p = e.GetPosition(this);

    目标位置 = new Point(p.- Ball.ActualWidth / 2, p.- Ball.ActualHeight / 2);

}

在此事件处理中,将目标位置设为鼠标当前坐标减去Ellipse元素的实际尺寸的一半,这样在移动完成后,球的中心点就位于鼠标的点击处了。

PS:将PreviewMouseLeftButtonDown事件改为MouseLeftButtonDown也是可行的,但是窗体内的控件如果截获并处理了点击事件,那么将不会引发球体移动。

现在编译和运行后,显示的程序界面效果如下:

通过点击可以使球移动,调整两个参数可以看到不同的移动效果。

你可以通过下面这个视频大略了解此示例的效果,但它与实际的流畅度有些差距,程序中的帧频应当是每秒100帧的,而视频只有每秒25帧。

源视频下载(清晰度高一些):http://www.box.net/shared/fjv5kucgns

本文章的PDF文档下载:http://www.box.net/shared/rlqoqf5lkp

源代码下载


本文转自斯克迪亚博客园博客,原文链接:http://www.cnblogs.com/SkyD/archive/2008/09/05/1284778.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java 专项练习【21- 30】(每日精进系列)
Java 专项练习【21- 30】(每日精进系列)
6 0
【Android RTMP】安卓直播推流总结 ( 直播服务器搭建 | NV21 图像采集 | H.264 视频编码 | PCM 音频采集 | AAC 音频编码 | RTMP 包封装推流 )
【Android RTMP】安卓直播推流总结 ( 直播服务器搭建 | NV21 图像采集 | H.264 视频编码 | PCM 音频采集 | AAC 音频编码 | RTMP 包封装推流 )
6 0
【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 )(一)
【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 )(一)
7 0
【计算机网络】物理层 : 编码与调制 ( 基带信号 | 宽带信号 | 编码 | 调制 )
【计算机网络】物理层 : 编码与调制 ( 基带信号 | 宽带信号 | 编码 | 调制 )
4 0
【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
11 0
【Android 性能优化】布局渲染优化 ( CPU 与 GPU 架构分析 | 安卓布局显示流程 | 视觉与帧率分析 | 渲染超时卡顿分析 | 渲染过程与优化 )
【Android 性能优化】布局渲染优化 ( CPU 与 GPU 架构分析 | 安卓布局显示流程 | 视觉与帧率分析 | 渲染超时卡顿分析 | 渲染过程与优化 )
5 0
Mono 现状与未来: 从 Xamarin 到 WebAssembly、Blazor 及.NET 5
  本文要点:   Mono 项目始于 2001 年,是首个面向.NET 应用程序的多平台、开源框架的项目。Xamarin 和 Blazor 分别代表了微软在移动和 Web 应用程序方面的努力,它们都是基于 Mono 并由 Mono 提供支持的。.NET 5 为用户提供了两种运行时选项:高性能的 CoreCLR(用于服务器和桌面应用程序)和轻量级的 Mono(用于移动设备和 WebAssembly)。尽管 Mono 已经是.NET 的一部分了,但仍有一些开发工作要致力于改善 Mono 的运行时性能和垃圾回收器。现在.NET Core 可以与 Mono 并行安装了,因此可以一起演进语言和运行时
3 0
【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
3 0
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频解码信息 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频解码信息 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
6 0
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
7 0
+关注
3546
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载