SkiaSharp 之 WPF 自绘弹跳球(案例版)

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

大概效果如下:.

SkiaSharp 之 WPF 自绘弹跳球(案例版)

原理分析

先是实现了网格效果,这个比较简单,直接横线,竖线,就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);
    }
}
}

效果

SkiaSharp 之 WPF 自绘弹跳球(案例版)

看着效果还是真不错。

总结

这个案例搞定,下一次,想想做个啥案例好点。

代码地址

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

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