SkiaSharp 之 WPF 自绘 五环弹动球(案例版)
此案例基于拖曳和弹动球两个技术功能实现,如有不懂的可以参考之前的相关文章,属于递进式教程。
五环弹动球
好吧,名字是我起的,其实,你可以任意个球进行联动弹动,效果还是很不错的,有很多前端都是基于这个特效,可以搞出一些很有科技感的效果出来。
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 自绘 五环弹动球(案例版)的更多相关文章
- SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)
此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...
- SkiaSharp 之 WPF 自绘 弹动小球(案例版)
没想到粉丝对界面效果这么喜欢,接下来就尽量多来点特效,当然,特效也算是动画的一部分了.WPF里面已经包含了很多动画特效的功能支持了,但是,还是得自己实现,我这边就来个自绘实现的. 弹动小球 弹动小球是 ...
- SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢. 刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例. 拖曳小球 WPF的拖 ...
- SkiaSharp 之 WPF 自绘 粒子花园(案例版)
此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...
- canvas检测边界和弹动的实例
如图所示的效果,小球相互碰撞会相互弹开,这时要干的事就只有两件事了,一:用二次循环遍历小球是否互相碰撞,二:碰撞之后会弹向什么地方和弹出多少距离,第一件事我想学过二维数组循环的都没问题,第二件事也只是 ...
- canvas弹动
弹动,和缓动类似,不过是在终点前反复运动几次达到反弹的效果,具体的算法就是用目标点(target)和物体(mouse)的距离乘以系数累加至坐标上,这样就会有简单的弹动效果,但是一般的弹动效果都是慢慢变 ...
- canvas弹动效果
弹动效果,用物体与目标的距离乘上系数再累加至速度上,让物体呈加速度运动,再让速度乘与摩擦力系数,让物体最终停止运动 代码如下所示 var canvas = document.getElementByI ...
- swift皮筋弹动发射飞机
今天在那个ios教程网上看到了一个不错的ios游戏源码,这是一个款采用swift实现的皮筋弹动发射飞机游戏源码,游戏源码比较详细,大家可以研究学习一下吧. <ignore_js_op> & ...
- 一款jQuery实现重力弹动模拟效果特效,弹弹弹,弹走IE6
一款jQuery实现重力弹动模拟效果特效 鼠标经过两块黑色div中间的红色线时,下方的黑快会突然掉落, 并在掉落地上那一刻出现了弹跳的jquery特效效果,非常不错,还兼容所有的浏览器, 适用浏览器: ...
随机推荐
- vivo 万台规模 HDFS 集群升级 HDFS 3.x 实践
vivo 互联网大数据团队-Lv Jia Hadoop 3.x的第一个稳定版本在2017年底就已经发布了,有很多重大的改进. 在HDFS方面,支持了Erasure Coding.More than 2 ...
- 好客租房7-React脚手架的使用
3.3在脚手架中使用React //第一步导入react import React from "React" import ReactDOM from "react-do ...
- BUUCTF刷题记录(更新中...)
极客大挑战 2019]EasySQL-1 直接通过输入万能密码:' or 1=1#实现注入: 思考:服务端sql语句应该为:select * from users where username='xx ...
- Golang可重入锁的实现
Golang可重入锁的实现 项目中遇到了可重入锁的需求和实现,具体记录下. 什么是可重入锁 我们平时说的分布式锁,一般指的是在不同服务器上的多个线程中,只有一个线程能抢到一个锁,从而执行一个任务.而我 ...
- 【clickhouse专栏】新建库角色用户初始化
一.创建新的database clickhouse创建数据库的语法几乎和其他的关系型数据库是一样的,区别就是clickhouse存在集群cluster和库引擎engine的概念,可以根据需要进行指定. ...
- go-zero微服务实战系列(三、API定义和表结构设计)
前两篇文章分别介绍了本系列文章的背景以及根据业务职能对商城系统做了服务的拆分,其中每个服务又可分为如下三类: api服务 - BFF层,对外提供HTTP接口 rpc服务 - 内部依赖的微服务,实现单一 ...
- 11.Firewalld防火墙
Firewalld防火墙 目录 Firewalld防火墙 Firewalld概述 Firewalld Firewalld和iptables的关系 netfilter Firewalld/iptable ...
- 【SpringBoot】快速入门
博客主页:准Java全栈开发工程师 00年出生,即将进入职场闯荡,目标赚钱,可能会有人觉得我格局小.觉得俗,但不得不承认这个世界已经不再是以一条线来分割的平面,而是围绕财富旋转的球面,成为有钱人不是为 ...
- 使用MySqlBulkLoader批量插入数据
最近在项目中遇到插入几万.几十万.几百万的数据到MYSQL数据库,使用EF插入会发现插入速度非常慢的场景, 数据量非常大时EF插入需要几十分钟,甚至几个小时,这样子的速度肯定不是我们所期望的. 后面经 ...
- 理解 Python 的 for 循环
在本篇博客中,我们将讨论 Python 中 for 循环的原理. 我们将从一组基本例子和它的语法开始,还将讨论与 for 循环关联的 else 代码块的用处. 然后我们将介绍迭代对象.迭代器和迭代器协 ...