title author date CreateTime categories
win10 uwp 萤火虫效果
lindexi
2018-08-10 19:16:51 +0800
2018-2-13 17:23:3 +0800
UWP win2d

本文在Nukepayload2指导下,使用他的思想用C#写出来。
本文告诉大家,如何使用 win2d 做出萤火虫效果。

安装 win2d

安装win2d的方法请使用 Nuget 下载的方法,参见:win10 uwp win2d

下面先让大家看一下效果图再告诉大家如何做

创建界面

界面只需要很简单两句代码,第一句代码是命名引用,第二句代码就是添加 win2d

    xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"

        <canvas:CanvasAnimatedControl x:Name="canvas" ClearColor="Black" Update="Canvas_OnUpdate" Draw="Canvas_Draw"></canvas:CanvasAnimatedControl>

这里为何使用 CanvasAnimatedControl 而不是使用 CanvasControl ?因为需要进行更新,CanvasAnimatedControl提供了一些事件,这些事件可以用来做动画。

后台的方法

Canvas_OnUpdate就写更新所有萤火虫的代码,在Canvas_Draw就写画出萤火虫的代码。

萤火虫

于是开始创建萤火虫的代码,在创建之前,需要一个随机的类,这个类用于控制萤火虫的呼吸和移动,都是随机的。

在指定的范围之内,随机取一个点,这个点作为目的的点。于是当前的值就开始移动向目的的点,移动的过程存在速度。

从这里可以知道,这个类需要下面这些属性

        public double Value { get; set; }
public double To { get; set; }
public double Dalue { get; set; } public double Ma { get; set; } public double Mi { get; set; } /// <summary>
/// 加速度
/// </summary>
public double Po { get; set; }

其中 Dalue 就是速度,从 Value 到 To 的速度,这个速度在随时可以被修改。

下面是这个类全部代码

    class Ran
{
public Ran(double value, double ma, double mi)
{
Value = value;
Ma = ma;
Mi = mi;
To = ran.NextDouble() * (Ma - Mi) + Mi;
} public double Value { get; set; }
public double To { get; set; }
public double Dalue { get; set; } public double Ma { get; set; } public double Mi { get; set; } public bool EasingFunction { get; set; } /// <summary>
/// 加速度
/// </summary>
public double Po { get; set; } public void Time(TimeSpan time)
{ if (Math.Abs(Dalue) < 0.000001)
{
if (Math.Abs(Po) < 0.0001)
{
Dalue = Math.Abs(Value - To) / ran.Next(10, 300);
}
else
{
Dalue = Po;
}
}
//减数
if (EasingFunction && Math.Abs(Value - To) < Dalue*10/*如果接近*/)
{
Dalue /= 2;
if (Math.Abs(Dalue) < 1)
{
Dalue = 1;
}
}
int n = 1;
if (Value > To)
{
n = n * -1;
}
Value += n * Dalue * time.TotalSeconds * 2;
if (n > 0 && Value >= To)
{
Value = To;
To = ran.NextDouble() * (Ma - Mi) + Mi;
Dalue = 0;
}
if (n < 0 && Value <= To)
{
Value = To;
To = ran.NextDouble() * (Ma - Mi) + Mi;
Dalue = 0;
}
} private static Random ran = new Random();
}

下面就是主要的类FireflyParticle包含了位置和颜色,不同透明度,当然不透明度可以做呼吸效果,于是这些值都需要做随机移动

    class FireflyParticle
{
public FireflyParticle(Rect bound)
{
Point = new Point(ran.Next((int) bound.Width), ran.Next((int) bound.Height));
_x = new Ran(Point.X, bound.Width, 0)
{
EasingFunction = true,
};
_y = new Ran(Point.Y, bound.Height, 0)
{
EasingFunction = true,
};
_radius = new Ran(ran.Next(2, 5), 5, 2)
{
Po = 0.71
};
Bound = bound;
} public FireflyParticle()
{
} public void Time(TimeSpan time)
{
_radius.Time(time);
_opColor.Time(time);
_x.Time(time);
_y.Time(time); Radius = _radius.Value;
OpColor = _opColor.Value;
Point = new Point(_x.Value, _y.Value);
} public Point Point { get; set; } public Rect Bound
{
get { return _bound; }
set
{
_bound = value;
_x.Ma = value.Width;
_y.Ma = value.Height;
}
} public double Radius { get; set; } = 10;
public Color CenterColor { get; set; } = Color.FromArgb(255, 252, 203, 89);
public double OpColor { set; get; } = 1;
private static Random ran = new Random(); private Ran _radius;
private Ran _opColor = new Ran(1, 1, 0.001); private Ran _x;
private Ran _y;
private Rect _bound;
}

看到这,是不是觉得参数存在 time 无法理解?这里的使用 time 是为了在性能比较差的电脑得到效果和性能比较好的一样,虽然中途有一些没有显示的,但是计算结果相同,不会出现性能差的电脑,动画速度和性能好的电脑不一样。

动画

下面就是更新所有的值,创建属性FireflyParticle用于放所有的类,因为很简单,我就不解释。

        private List<FireflyParticle> FireflyParticle { set; get; } = new List<FireflyParticle>();

        private void BpyaxxjwkQwknemobzPage_Loaded(object sender, RoutedEventArgs e)
{
if (!FireflyParticle.Any())
{
Rect bound = new Rect(0, 0, canvas.ActualWidth, canvas.ActualHeight);
for (int i = 0; i < 100; i++)
{
FireflyParticle.Add(new FireflyParticle(bound));
}
}
} private void Canvas_OnUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs args)
{
foreach (var temp in FireflyParticle)
{
temp.Time(args.Timing.ElapsedTime);
}
}

把所有的值都进行变化,就是在做动画,但是移动距离不能太长,移动的算法在上面的随机类写的,算法很简单,也不是关键,于是在这里就不说了。

核心代码

这里的核心就是画出来,如何在 win2d 画出一个点,把这个点高斯模糊。不知道大家知道 PhotoShop ,这里用到了图层,需要自己心中知道是什么东西。现在的图片一般都是很多个图片合成,于是可以把一个点作为一个图层,到时候把这些点合并就是上面给大家看到的图。

如何在 win2d 使用图层,主要的类是CanvasCommandList用它就可以做出图层,最好使用DrawImage把他弄出来。

      private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
using (var session = args.DrawingSession)
{
using (var cl = new CanvasCommandList(session))
using (var ds = cl.CreateDrawingSession())
{
//这里就是图层
// session.DrawImage(cl); 把 图层画出来 }
}
}

如何对图层做模糊?在win2d有很多效果,先尝试把点画出来,效果图:

需要知道所有的效果都是可以直接画出来,我用的方法很简单,就直接写代码

   class GlowEffectGraph : IDisposable
{
private MorphologyEffect morphology;
public GlowEffectGraph()
{
Blur.BlurAmount = 10;
Blur.BorderMode = EffectBorderMode.Soft; morphology = new MorphologyEffect()
{
Mode = MorphologyEffectMode.Dilate,
Width = 10,
Height = 10,
}; Blur.Source = morphology; } public GaussianBlurEffect Blur { get; set; } = new GaussianBlurEffect(); public void Dispose()
{
Blur.Dispose();
morphology.Dispose();
} public void Setup(ICanvasImage canvas, double amount = 10)
{
morphology.Source = canvas;
amount = Math.Min(amount / 2, 100);
morphology.Width = (int) Math.Truncate(Math.Floor(amount));
morphology.Height = (int) Math.Truncate(Math.Floor(amount));
Blur.BlurAmount = (float) amount;
}
}

如何要把图层画出来,那么修改Canvas_Draw的代码

     private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
using (var session = args.DrawingSession)
{
foreach (var temp in FireflyParticle)
{
using (var cl = new CanvasCommandList(session))
using (var ds = cl.CreateDrawingSession())
{
var c = temp.CenterColor;
c.A = (byte) (temp.OpColor * 255);
ds.FillCircle((float) temp.Point.X, (float) temp.Point.Y, (float) temp.Radius, c);
using (var glow = new GlowEffectGraph())
{
glow.Setup(cl, temp.Radius);
session.DrawImage(glow.Blur);
}
}
}
}
}

<script src='https://gitee.com/lindexi/codes/m90sfzgdwqvk6j81au2y445/widget_preview?title=%E8%90%A4%E7%81%AB%E8%99%AB%E6%95%88%E6%9E%9C+Canvas_Draw+2'></script>

这个效果我放在 商业游戏 可以玩一下,代码开源https://github.com/lindexi/UWP/tree/master/uwp/src/VarietyHiggstGushed

参见:使用win2d实现萤火虫粒子效果 - Nukepayload2 - 博客园

2018-8-10-win10-uwp-萤火虫效果的更多相关文章

  1. win10 uwp 萤火虫效果

    原文:win10 uwp 萤火虫效果 本文在Nukepayload2指导下,使用他的思想用C#写出来. 本文告诉大家,如何使用 win2d 做出萤火虫效果. 安装 win2d 安装win2d的方法请使 ...

  2. win10 uwp 视差效果

    本文翻译:http://jamescroft.co.uk/blog/uwp/playing-with-scrolling-parallax-effects-on-ui-elements-in-wind ...

  3. win10 UWP 蜘蛛网效果

    我看见了知乎首页登录背景和普通的地球人写的博客,发现了个好看的效果. 那么我来告诉大家如何做这个效果. 第一步是在 Canvas 画点,第二步是让点移动,第三步是画线 在 Canvas 画一个点 我们 ...

  4. win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl

    本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ...

  5. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  6. win10 uwp 毛玻璃

    毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ...

  7. win10 uwp 渲染原理 DirectComposition 渲染

    本文来告诉大家一个新的技术DirectComposition,在 win7 之后(实际上是 vista),微软正在考虑一个新的渲染机制 在 Windows Vista 就引入了一个服务,桌面窗口管理器 ...

  8. win10 uwp 线程池

    原文:win10 uwp 线程池 如果大家有开发 WPF 或以前的程序,大概知道线程池不是 UWP 创造的,实际上在很多技术都用到线程池. 为什么需要线程池,他是什么?如何在 UWP 使用线程池,本文 ...

  9. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  10. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

随机推荐

  1. text()和html()区别

    这两天看了一下html和jquery的选择器,并对w3chool上面的在线编辑产生了兴趣,但是在用textarea展示后台纯html的时候发生错误,查阅各种资料发现不行--心态炸了.废话不多说了,上干 ...

  2. Directx11教程(18) D3D11管线(7)

    原文:Directx11教程(18) D3D11管线(7) 光栅化阶段(RS)之后,将进入PS/OM阶段. 参考外文资料:http://fgiesen.wordpress.com/2011/07/01 ...

  3. php的一些误解

    1.php函数和方法是不用的:类的方法可以设定访问权限,需要通过对象或者类来调用:函数是公共的,都可以使用.

  4. JavaScript--兼容问题总结

    以下兼容主要面向IE8以上的兼容. 一.window.navigator浏览器信息 <script> console.log(window.navigator); // 用户浏览器的类型 ...

  5. python 解释器编码

  6. Xcode 中的Bundle versions string, short 和 Bundle version 区别

    Bundle version is the internal version number of your app. Short version string is the publically vi ...

  7. (转)理解inode

    作者:阮一峰 原文链接:http://www.ruanyifeng.com/blog/2011/12/inode.html 一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上 ...

  8. 【vb.net机房收费系统】之没有包含要从继承的组件的已生成程序集 标签: vb.net继承 2015-05-02 15:19 1012人阅读

    在敲到组合查询这个功能的时候,需要用到窗体的继承,但是在新建继承窗体的时候,出现了错误(没有包含要从继承的组件的已生成程序集).如下图: 问题的产生:当时没怎么注意,也不知道怎么弄的,最后反正是继承上 ...

  9. QT 中如何实现一个简单的动画

    QT可以实现一下简单的动画,比如 运动的时钟 闪烁的按钮. 动画的实现: (1)创建一个定时器 (2)调用QWidget::update()通知界面重绘 实现一个按钮闪烁的例子: circlewidg ...

  10. oracle函数 SOUNDEX(c1)

    [功能]返回字符串参数的语音表示形式 [参数]c1,字符型 [返回]字符串 [说明]相对于比较一些读音相同,但是拼写不同的单词是非常有用的. 计算语音的算法: 1.保留字符串首字母,但删除a.e.h. ...