用.NET做圣诞节音乐盒

用.NET做圣诞节音乐盒

我曾经用这个程序送给我女朋友(现老婆):blush:……首先来看一下最终运行效果:

(当然还有一首《We wish you Merry Christmas》的八音盒 BGM ,但由于  gif 的关系,你们 可能 听不到。)

雪花是怎么做的?

首先本文将着重讲解代码,因此所有的资源都将在运行时下载,雪的的资源是从“码云”下载的,地址如下:https://gitee.com/sdcb/lovegl/raw/master/lovegl2014/icon1.ico

其显示效果如下:

那么是怎么让其旋转起来的呢?我写了一个 Snow 类,用来表示雪花:

注意它存储了雪花的坐标 X 、  Y 、放大比例  Scale 、注意我并没有使用矢量类型  Vector2 ,因此速度描述拆分成了角速度  AngularSpeed 、线速度  Speed 、当前的旋转角  RotationAngle 和运行方向  Direction 几个变量。另外还有一个帮助属性  IsOffScreen 用于判断雪花是否仍然在屏幕上。

雪花运行时,我通过一个 Update 函数来控制这些属性的变化:

然后通过一个矩阵变换,即可完成雪花的平衡、缩放和旋转:

注意第一个 -24 ,指的是先平衡到雪花的中心间  (-24,-24) ,然后再依次旋转、缩放和平移。

最后,还需要一个函数,用于随机在屏幕上生成不同大小、不同方向、不同线速度、不同角速度的雪花:

音乐是怎么播放的?

音乐也是从“码云”上下载的,当初搞 C++ 版的时间为了节省资源文件,音乐部分我做成了一个代码文件,该文件地址如下:https://gitee.com/sdcb/lovegl/raw/master/lovegl2014/music.cpp

它的本质是一个 .mid 文件。解析一个  C++ 文件可能很复杂,但细一看,会发现这个  C++ 文件很有规律: 

除了第一行那个声明外,里面的资源都是一个个的字节字面量,因此可以使用 C# 的  LINQ 和  定则表达式 不费吹灰之力即可将其解析出来:

最后通过 WindowsAPI 的  mciSendString 函数,将其播放:

注意通过 mciSendString 播放的音乐在播放完成后,并不像  .NET API 返回一个  Task 这样方便,而是通过发送一个  MM_MCINOTIFY 的窗体事件,因此需要多花几行代码搞定循环播放这件事:

最后,循环播放的圣诞彩灯

以防没人注意到,我先来个特写(注意那三个灯是旋转播放的):

这实际上是由三张图片组成:

要定期循环播放,我定义了一个 Timer ,定时  500 毫秒,然后修改当前显示的图片索引即可:

然后渲染时,显示为“当前”的那张图片:

至于为何它也能拖拽,因为我取了个巧,这里我创建了两个窗口,让这个整个窗口显示 MerryChristmas 的图片,然后使之可以拖拽即可:

总结

其实这并不是我的发明,这个早在我上大学时 WindowsXP 时代就看到过,我的大学室友都觉得它很炫酷,于是我进行了很久很久的探索。

最开始的时候,我使用 WPF 对其进行了“仿制”,通过  WPF 中的  AllowsTransparency=true 来达到屏幕透明的效果。但其性能低下,  CPU 使用率往往徘徊在  13% 左右(单核  100% )。

后来我了解到 Direct2D 以及  UpdateLayeredWindowIndirect 方法,所以我立即用  C++ 再对这个程序进行了重制。  CPU 使用率降低至  0% 。  C++ 代码已在 5年前 开源在“码云”(这个也是我当年送给我女朋友的版本):https://gitee.com/sdcb/lovegl/

再后来……直到最近, .NET 革命再次爆发,我又拿起了最拿手的  C# ,基于我做的  FlysEngine 再次对其进行了重制。这次重制的原则是对新手友好,因此代码尽可能简短,一个文件搞定,不要用项目,因此所有资源文件都是运行时从“码云”下载。

说了这么多,我也曾对这个最早的、别人写的这个程序进行了一定的研究,我发现他并没有使用 Direct2D ,而是用的最简单的  GDI 和多窗口模式,每个雪花都是一个窗口。然后它的定时器时间设得比较长,因此雪花旋转并不像我的这样平滑,因此他的那个程序也能在保持  CPU 使用率相对较低的同时确保用户体验。

福利:所有这些可运行、完整的代码,都可以在我的  Github 博客数据上进行下载:https://github.com/sdcb/blog-data/tree/master/2019/20191225-merry-christmas-by-dotnet

扫码求关注

给我好看

您看此文用

·

秒,转发只需1秒呦~

好看你就

点点

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章