鱼,鱼,鱼






4.90/5 (40投票s)
仅为好玩;
- HockeyApp AppX page (如果你想作为 UWP 应用程序侧加载)
- 下载 fishtank.zip - 2.8 MB
- 下载源代码 - 2.5 MB
引言
这篇文章是对 Davidwu 的优秀文章 一个可爱的金鱼桌面宠物 的致敬。 在那篇文章中,David 演示了使用 alpha 混合和 GDI+ 来制作一条小鱼在屏幕上游动。
我已经采用了该代码并扩展了它以支持多条鱼,以及一个 SysTray 图标来控制您的鱼缸中的鱼的数量。
我还添加了一些不同颜色的鱼的图像,以增加一些多样性。
Using the Code
该代码与原始代码基本相同,尽管我稍微调整了一下以支持多条鱼。 与原始代码不同的是,帧是在启动时从源 PNG 提取的,而不是在每个计时器滴答声时提取。
class Frameset : List<Bitmap>, IDisposable
{
public Frameset(Bitmap b, int framecount)
{
if (!Bitmap.IsCanonicalPixelFormat(b.PixelFormat) ||
!Bitmap.IsAlphaPixelFormat(b.PixelFormat))
throw new ApplicationException("The picture must be 32bit
picture with alpha channel.");
FrameWidth = b.Width / framecount;
FrameHeight = b.Height;
for (int i = 0; i < framecount; i++)
{
Bitmap bitmap = new Bitmap(FrameWidth, FrameHeight);
using (Graphics g = Graphics.FromImage(bitmap))
g.DrawImage(b, new Rectangle(0, 0, FrameWidth, FrameHeight),
new Rectangle(FrameWidth * i, 0, FrameWidth, FrameHeight),
GraphicsUnit.Pixel);
Add(bitmap);
}
}
public int FrameWidth { get; private set; }
public int FrameHeight { get; private set; }
public void Dispose()
{
foreach (Bitmap f in this)
f.Dispose();
Clear();
}
}
这大大降低了动画的 CPU 使用率,这对于整个鱼缸游泳来说非常重要。 还有一个从主 FishForm
派生的 Form 来托管系统托盘中的 NotifyIcon
。 此窗体的实例将始终是第一个创建的。 NotifyIcon
上下文菜单允许用户添加和删除鱼,显示和隐藏所有鱼,当然还有退出应用程序。
.NET 4
项目文件都在 VS.NET 2010 格式中,但唯一使用的 .NET 4 类型是 Tuple
。 Sacha 在下面的评论中发布了一个 Tuple
的版本。 因此,如果您想在 2008 和 .NET 3.5 中使用它,您需要合并该代码片段或以其他方式替换 Tuple
的用法,这应该不会太难。
转换为 UWP
随着 Windows 10 周年纪念版的发布以及 Desktop App Converter 的引入,我决定看看这是否可以作为 UWP 应用程序运行。 整个转换过程非常简单。
1) 第一步是将项目从 vs.net 2010 更新到 2015 (特别是 15 Release 3 Preview - 稍后会详细介绍),然后以 .NET 4.6.1 为目标。 没有任何问题。
2) 接下来,需要创建一个 UWP AppXManifest 布局文件。 我决定采用 手动方式,因为这个东西可以 xcopy 部署。 清单尽可能简单。 真正最难的部分是让我自己重新熟悉应用程序签名。 最后,我添加了几个构建事件脚本,每次构建时都会使用它们来重建 appx 包。 将其和一些 logo png 放入解决方案文件夹中。
AppXManifest.xml
<?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"> <Identity Name="[this is the guid of your package]" ProcessorArchitecture="x86" Publisher="CN=kackman.net" Version="1.1.11.0" /> <Properties> <DisplayName>Fishy Fishy Fish</DisplayName> <PublisherDisplayName>Reserved</PublisherDisplayName> <Description>Some fish. Swimming around on your screen.</Description> <Logo>StoreLogo.png</Logo> </Properties> <Resources> <Resource Language="en-us" /> </Resources> <Dependencies> <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14316.0" MaxVersionTested="10.0.14393.0" /> </Dependencies> <Capabilities> <rescap:Capability Name="runFullTrust"/> </Capabilities> <Applications> <Application Id="FishyFishyFish" Executable="FishyFish.exe" EntryPoint="Windows.FullTrustApplication"> <uap:VisualElements BackgroundColor="transparent" DisplayName="Fishy Fishy Fish" Square150x150Logo="Square150x150Logo.png" Square44x44Logo="Square44x44Logo.png" Description="Some fish. Swimming around on your screen." /> </Application> </Applications> </Package>
构建前
:: clean any previous AppX outputs rmdir AppX /s /q del $(TargetName).appx /q /f
构建后
:: copy all of the files that go into the AppX into a working folder mkdir AppX xcopy "$(TargetPath)" AppX\ /R /Y xcopy "$(TargetPath).config" AppX\ /R /Y xcopy "$(SolutionDir)appxmanifest.xml" AppX\ /R /Y xcopy "$(SolutionDir)StoreLogo.png" AppX\ /R /Y xcopy "$(SolutionDir)Square44x44Logo.png" AppX\ /R /Y xcopy "$(SolutionDir)Square150x150Logo.png" AppX\ /R /Y :: build a new AppX package "$(Win10SDKDir)MakeAppX.exe" pack /d AppX /p $(TargetName).appx "$(Win10SDKDir)SignTool.exe" sign -f d:\temp\tempca.pfx -fd SHA256 -v .\$(TargetName).appx
$(Win10SDKDir)
是一个添加到 csproj
文件中的变量,它指向 Windows 10 SDK 文件夹。)<PropertyGroup> <Win10SDKDir Condition=" '$(Win10SDKDir)' == '' ">C:\Program Files (x86)\Windows Kits\10\bin\x64\</Win10SDKDir> </PropertyGroup>
结论
哦,而且我在鱼的着色上作弊了。 我在 Paint.Net 中对源 PNG 进行了颜色偏移,并将每个 PNG 保存为一组新的图像。 这就是项目大小大的原因。 也许有一天我会纠正那个捷径,但现在为额外的下载量表示歉意。 :)
大致就是这样了。 这是一个有趣的、可以玩的小项目(我给它的人和朋友也很喜欢它)。 这可能是我最后一篇 WinForms 文章。 我已经感染了 WPF 病毒,并且终于开始克服学习曲线。
历史
- 2010 年 3 月 31 日 - 初始帖子
- 2016 年 8 月 3 日 - UWP 部分