此案例基于拖曳和弹动球两个技术功能实现,如有不懂的可以参考之前的相关文章,属于递进式教程。

五环弹动球

好吧,名字是我起的,其实,你可以任意个球进行联动弹动,效果还是很不错的,有很多前端都是基于这个特效,可以搞出一些很有科技感的效果出来。

Wpf 和 SkiaSharp

新建一个WPF项目,然后,Nuget包即可

要添加Nuget包

Install-Package SkiaSharp.Views.WPF -Version 2.88.0

其中核心逻辑是这部分,会以我设置的60FPS来刷新当前的画板。

skContainer.PaintSurface += SkContainer_PaintSurface;
_ = Task.Run(() =>
{
while (true)
{
try
{
Dispatcher.Invoke(() =>
{
skContainer.InvalidateVisual();
});
_ = SpinWait.SpinUntil(() => false, 1000 / 60);//每秒60帧
}
catch
{
break;
}
}
});

弹球实体代码 (Ball.cs)

public class Ball
{
public double X { get; set; }
public double Y { get; set; }
public double VX { get; set; }
public double VY { get; set; }
public int Radius { get; set; }
public bool Dragged { get; set; } = false;
public SKColor sKColor { get; set; } = SKColors.Blue;
public bool CheckPoint(SKPoint sKPoint)
{
var d = Math.Sqrt(Math.Pow(sKPoint.X - X, 2) + Math.Pow(sKPoint.Y - Y, 2));
return this.Radius >= d;
}
}

五环弹动核心类 (FiveRings.cs)

/// <summary>
/// 五环弹球
/// </summary>
public class FiveRings
{
public SKPoint centerPoint;
public int Radius = 0;
public int BallLength = 8; public double TargetX;
public double Spring = 0.03;
public double SpringLength = 200;
public double Friction = 0.95;
public List<Ball>? Balls;
public Ball? draggedBall;
public void init(SKCanvas canvas, SKTypeface Font, int Width, int Height)
{
if (Balls == null)
{
Balls = new List<Ball>();
for (int i = 0; i < BallLength; i++)
{
Random random = new Random((int)DateTime.Now.Ticks);
Balls.Add(new Ball()
{
X = random.Next(50, Width - 50),
Y = random.Next(50, Height - 50),
Radius = this.Radius
});
}
}
}
/// <summary>
/// 渲染
/// </summary>
public void Render(SKCanvas canvas, SKTypeface Font, int Width, int Height)
{
centerPoint = new SKPoint(Width / 2, Height / 2);
this.Radius = 20;
this.TargetX = Width / 2;
init(canvas, Font, Width, Height);
canvas.Clear(SKColors.White); //划线
using var LinePaint = new SKPaint
{
Color = SKColors.Green,
Style = SKPaintStyle.Fill,
StrokeWidth = 3,
IsStroke = true,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
SKPath path = null;
foreach (var item in Balls)
{
if (path == null)
{
path = new SKPath();
path.MoveTo((float)item.X, (float)item.Y);
}
else
{
path.LineTo((float)item.X, (float)item.Y);
}
}
path.Close();
canvas.DrawPath(path, LinePaint); foreach (var item in Balls)
{
if (!item.Dragged)
{
foreach (var ball in Balls.Where(t => t != item).ToList())
{
SpringTo(item, ball);
}
}
DrawCircle(canvas, item);
} using var paint = new SKPaint
{
Color = SKColors.Blue,
IsAntialias = true,
Typeface = Font,
TextSize = 24
};
string by = $"by 蓝创精英团队";
canvas.DrawText(by, 600, 400, paint); }
/// <summary>
/// 画一个圆
/// </summary>
public void DrawCircle(SKCanvas canvas, Ball ball)
{
using var paint = new SKPaint
{
Color = SKColors.Blue,
Style = SKPaintStyle.Fill,
IsAntialias = true,
StrokeWidth = 2
};
canvas.DrawCircle((float)ball.X, (float)ball.Y, ball.Radius, paint);
}
public void MouseMove(SKPoint sKPoint)
{
if (draggedBall != null)
{
draggedBall.X = sKPoint.X;
draggedBall.Y = sKPoint.Y;
}
}
public void MouseDown(SKPoint sKPoint)
{
foreach (var item in Balls)
{
if (item.CheckPoint(sKPoint))
{
item.Dragged = true;
draggedBall = item;
}
else
{
item.Dragged = false;
}
}
}
public void MouseUp(SKPoint sKPoint)
{
draggedBall = null;
foreach (var item in Balls)
{
item.Dragged = false;
}
}
public void SpringTo(Ball b1, Ball b2)
{
var dx = b2.X - b1.X;
var dy = b2.Y - b1.Y;
var angle = Math.Atan2(dy, dx);
var targetX = b2.X - SpringLength * Math.Cos(angle);
var targetY = b2.Y - SpringLength * Math.Sin(angle); b1.VX += (targetX - b1.X) * Spring;
b1.VY += (targetY - b1.Y) * Spring; b1.VX *= Friction;
b1.VY *= Friction; b1.X += b1.VX;
b1.Y += b1.VY;
}
}

效果如下:

这个特效用的好,也能产生一些神奇的效果。

总结

这次是结合拖曳和弹动效果实现的综合案例,效果还是很不错的,之前也没想到原来还可以这样玩,拓展了玩法啊。

代码地址

https://github.com/kesshei/WPFSkiaFiveRingsDemo.git

https://gitee.com/kesshei/WPFSkiaFiveRingsDemo.git

一键三连呦!,感谢大佬的支持,您的支持就是我的动力!

版权

蓝创精英团队(公众号同名,CSDN同名,CNBlogs同名)

SkiaSharp 之 WPF 自绘 五环弹动球(案例版)的更多相关文章

  1. SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)

    此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...

  2. SkiaSharp 之 WPF 自绘 弹动小球(案例版)

    没想到粉丝对界面效果这么喜欢,接下来就尽量多来点特效,当然,特效也算是动画的一部分了.WPF里面已经包含了很多动画特效的功能支持了,但是,还是得自己实现,我这边就来个自绘实现的. 弹动小球 弹动小球是 ...

  3. SkiaSharp 之 WPF 自绘 拖曳小球(案例版)

    感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢. 刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例. 拖曳小球 WPF的拖 ...

  4. SkiaSharp 之 WPF 自绘 粒子花园(案例版)

    此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...

  5. canvas检测边界和弹动的实例

    如图所示的效果,小球相互碰撞会相互弹开,这时要干的事就只有两件事了,一:用二次循环遍历小球是否互相碰撞,二:碰撞之后会弹向什么地方和弹出多少距离,第一件事我想学过二维数组循环的都没问题,第二件事也只是 ...

  6. canvas弹动

    弹动,和缓动类似,不过是在终点前反复运动几次达到反弹的效果,具体的算法就是用目标点(target)和物体(mouse)的距离乘以系数累加至坐标上,这样就会有简单的弹动效果,但是一般的弹动效果都是慢慢变 ...

  7. canvas弹动效果

    弹动效果,用物体与目标的距离乘上系数再累加至速度上,让物体呈加速度运动,再让速度乘与摩擦力系数,让物体最终停止运动 代码如下所示 var canvas = document.getElementByI ...

  8. swift皮筋弹动发射飞机

    今天在那个ios教程网上看到了一个不错的ios游戏源码,这是一个款采用swift实现的皮筋弹动发射飞机游戏源码,游戏源码比较详细,大家可以研究学习一下吧. <ignore_js_op> & ...

  9. 一款jQuery实现重力弹动模拟效果特效,弹弹弹,弹走IE6

    一款jQuery实现重力弹动模拟效果特效 鼠标经过两块黑色div中间的红色线时,下方的黑快会突然掉落, 并在掉落地上那一刻出现了弹跳的jquery特效效果,非常不错,还兼容所有的浏览器, 适用浏览器: ...

随机推荐

  1. Vue的Vuex的使用

    一.Vuex是什么? 1:Vuex是一个专为vue.js应用程序开发的状态管理模式,核心就是一个store仓库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ...

  2. 无线:WPA

    WPA全名为Wi-Fi Protected Access,有WPA和WPA2两个标准,是一种保护无线电脑网络(Wi-Fi)安全的系统,它是应研究者在前一代的系统有线等效加密(WEP)中找到的几个严重的 ...

  3. ID为XXXX的进程当前未运行

    项目文件夹下,有个.vs的文件夹,删除掉,然后重新打开项目就ok了. 或者: 在启动项目根目录下用文本编辑器打开Web项目下的{X}.csproj文件,然后查找 <WebProjectPrope ...

  4. 脚踏实地的Netty源码研究笔记——开篇

    1. 脚踏实地的Netty源码研究笔记--开篇 1.1. Netty介绍 Netty是一个老牌的高性能网络框架.在众多开源框架中都有它的身影,比如:grpc.dubbo.seata等. 里面有着非常多 ...

  5. 2021年第十二届蓝桥杯javaA组省赛部分题目

    试题 D: 路径 本题总分:10 分 [问题描述] 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径. 小蓝的图由 2021 个结点组成,依次编号 1 至 2021. 对 ...

  6. React简单教程-3.1-样式之使用 tailwindcss

    前言 本文是作为一个额外内容,主要介绍 tailwindcss 的用法 tailwindcss 是一个功能类优先的 CSS 框架,我在以前的文章里有描述为什么使用功能类优先:为什么我在 css 里使用 ...

  7. 如何用 UDP 实现可靠传输?

    作者:小林coding 计算机八股文刷题网站:https://xiaolincoding.com 大家好,我是小林. 我记得之前在群里看到,有位读者字节一面的时候被问到:「如何基于 UDP 协议实现可 ...

  8. ER图/模型转换为关系模型

    ER图中的主要成分是实体类型和联系类型,转换规则就是如何把实体类型.联系类型转换成关系模式. 1. 二元联系转换 规则1.1(实体类型的转换):将每个实体类型转换成一个关系模式,实体的属性即为关系模式 ...

  9. python实现对简单的运算型验证码的识别【不使用OpenCV】

    最近在写我们学校的教务系统的手机版,在前端用户执行绑定操作后,服务器将执行登录,但在登录过程中,教务系统中有个运算型的验证码,大致是这个样子的: 下面我们开始实现这个验证码的识别. 1.图片读取 从网 ...

  10. Lucene从入门到实战

    Lucene 在了解Lucene之前,我们先了解下全文数据查询. 全文数据查询 我们的数据一般分为两种:结构化数据和非结构化数据 结构化数据:有固定格式或有限长度的数据,如数据库中的数据.元数据 非结 ...