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

五环弹动球

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

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. 143_Power BI&Power Pivot月度、季度、半年度、全年同维度展示

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最近在做下一年度的预算,做出来需要月度.季度.半年度.全年都展示出来,在做测算的是时候,默认的透视表已经无法满足 ...

  2. 通过一次生产case深入理解tomcat线程池

    最近生产上遇到一个case,终于想明白了原因,今天周末来整理一下 生产case 最近测试istio mesh的预热功能(调用端最小连接数原则) 来控制调用端进入k8s刚扩出来的容器的流量 因为刚启动的 ...

  3. (C++)读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔)

    1 /* 2 程序功能:读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔). 3 例如:当输入985这个数字时,显示如下信息: 4 985是一个3位数字! ...

  4. SQL语句修改MySQL用户密码

    SQL语句修改MySQL用户密码 前言 上数据库安全实验课,用命令行和DataGrip试图修改用户密码,一直语法报错.最后用Navicat才修改成功,预览Navicat的SQL语句,发现语句和网上都不 ...

  5. Gitee整改之思考

    本文主要内容如下: 1.Gitee是什么? 2.Gitee与Github的区别有哪些? 3.为什么要使用Gitee? 4.Gitee的商业模式是怎样的? 5.Gitee为何会被整改? 6.Gitee这 ...

  6. 关于升级最新版本node.js你知道多少?

    1.先检查版本 node -v 2.清除缓存 npm cache clean -f 3.全局安装管理node.js版本工具 npm install -g n 4.确认安装最新版本 n stable 5 ...

  7. 『现学现忘』Docker基础 — 38、COPY指令和ADD指令

    目录 1.COPY指令 (1)COPY指令说明 (2)COPY指令格式 (3)COPY指令使用 (4)其他 2.ADD指令 (1)ADD指令说明 (2)ADD指令格式 (3)ADD指令使用 (4)不推 ...

  8. Leetcode----<Re-Space LCCI>

    题解如下: /** * 动态规划解法: * dp[i] 表示 0-i的最小不能被识别的字母个数 * 求 dp[k] 如果第K个字母 不能和前面的字母[0-{k-1}]合在一起被识别 那么dp[k] = ...

  9. UiPath官方视频Level1

    [UiPath官方视频Level1]第一课-UiPath简介https://www.bilibili.com/video/BV1zJ41187vB [UiPath官方视频Level1]第二课-变量和数 ...

  10. python小题目练习(一)

    题目:输出1+2+3+4+5+--+100的总数,并打印出这行式子 代码展示:# 1.定义一个初识变量total,用于后面每次循环进行累加值 total = 0# 2.利用for循环遍历累加for i ...