熟悉下SkiaSharp的基础操作,这次搞个弹跳球效果,实现后,发现效果还真不错。
大概效果如下:.

原理分析
先是实现了网格效果,这个比较简单,直接横线,竖线,就OK了。
另外一个就是随机一个圆形,我这边随机了一百个,初始位置大致都一样,但是,每个方向角度随机,颜色随机,移动速度随机。
然后,它们移动起来,遇到了墙壁就会自动回弹回去,形成了不错的视觉效果。
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;
}
}
});
实现代码的圆形逻辑
/// <summary>
/// 圆圈
/// </summary>
internal class Circles
{
private Random r = new Random();
public Circles()
{
VelocityX = GetRandom(0, 3);
VelocityY = GetRandom(0, 3);
Radius = GetRandom(0, 50);
Color = new SKColor((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255));
}
public float X { get; set; } = 100;
public float Y { get; set; } = 100;
public float VelocityX { get; set; }
public float VelocityY { get; set; }
public float Radius { get; set; }
public SKColor Color { get; set; }
public float GetRandom(int min, int max)
{
var result = r.Next(min * 100, max * 100);
return (float)(result / 100.0);
}
}
圆形的移动逻辑
/// <summary>
/// 调整位置
/// </summary>
public void AdjustPosition(SKCanvas canvas, SKTypeface Font, int Width, int Height)
{
foreach (var circle in circles)
{
using var paint = new SKPaint
{
Color = circle.Color,
Style = SKPaintStyle.Fill,
IsAntialias = true,
StrokeWidth = 1
};
canvas.DrawCircle(circle.X, circle.Y, circle.Radius, paint);
if (circle.X + circle.VelocityX + circle.Radius > Width || circle.X + circle.VelocityX - circle.Radius < 0)
{
circle.VelocityX = -circle.VelocityX;
}
if (circle.Y + circle.VelocityY + circle.Radius > Height || circle.Y + circle.VelocityY - circle.Radius < 0)
{
circle.VelocityY = -circle.VelocityY;
}
circle.X += circle.VelocityX;
circle.Y += circle.VelocityY;
}
}
实现网格的逻辑
/// <summary>
/// 画格子
/// </summary>
public void DrawGrid(SKCanvas canvas, SKColor sKColor, int Width, int Height, int StepX, int StepY)
{
using var paint = new SKPaint
{
Color = sKColor,
Style = SKPaintStyle.Stroke,
StrokeWidth = 0.5f,
IsStroke = true,
IsAntialias = true
};
for (var i = 0.5; i < Width; i += StepX)
{
var path = new SKPath();
path.MoveTo((float)i, 0);
path.LineTo((float)i, Height);
path.Close();
canvas.DrawPath(path, paint);
}
for (var i = 0.5; i < Height; i += StepY)
{
var path = new SKPath();
path.MoveTo(0, (float)i);
path.LineTo(Width, (float)i);
path.Close();
canvas.DrawPath(path, paint);
}
}
}
效果
看着效果还是真不错。
总结
这个案例搞定,下一次,想想做个啥案例好点。
代码地址
https://github.com/kesshei/BouncingBallsDemo.git
https://gitee.com/kesshei/BouncingBallsDemo.git