欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WPF+SkiaSharp實(shí)現(xiàn)自繪投籃小游戲

 更新時(shí)間:2022年08月05日 11:04:22   作者:藍(lán)創(chuàng)精英團(tuán)隊(duì)  
這篇文章主要介紹了如何利用WPF+SkiaSharp實(shí)現(xiàn)自繪投籃小游戲。此案例主要是針對(duì)光線投影法碰撞檢測(cè)功能的示例,順便做成了一個(gè)小游戲,很簡(jiǎn)單,但是,效果卻很不錯(cuò),感興趣的可以動(dòng)手嘗試一下

投籃小游戲

規(guī)則,點(diǎn)擊投籃目標(biāo)點(diǎn),就會(huì)有一個(gè)球沿著相關(guān)拋物線,然后,判斷是否進(jìn)入籃子里,其實(shí)就是一個(gè)矩形,直接是按照碰撞檢測(cè)來(lái)的,碰到就算進(jìn)去了,對(duì)其增加了一個(gè)分?jǐn)?shù)統(tǒng)計(jì)等功能。

Wpf 和 SkiaSharp

新建一個(gè) WPF 項(xiàng)目,然后,Nuget 包即可

要添加 Nuget 包

Install-Package SkiaSharp.Views.WPF -Version 2.88.0

其中核心邏輯是這部分,會(huì)以我設(shè)置的 60FPS 來(lái)刷新當(dāng)前的畫(huà)板。

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

彈球?qū)嶓w代碼 (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; }
}

粒子花園核心類 (ParticleGarden.cs)

/// <summary>
/// 光線投影法碰撞檢測(cè)
/// 投籃小游戲
/// </summary>
public class RayProjection
{
    public SKPoint centerPoint;
    public double G = 0.3;
    public double F = 0.98;
    public double Easing = 0.03;
    public bool IsMoving = false;
    public SKPoint CurrentMousePoint = SKPoint.Empty;
    public SKPoint lastPoint = SKPoint.Empty;
    public Rect Box;
    public Ball Ball;
    public SKCanvas canvas;
    public int ALLCount = 10;
    public List<bool> bools = new List<bool>();
    public bool IsOver = false;
    /// <summary>
    /// 渲染
    /// </summary>
    public void Render(SKCanvas canvas, SKTypeface Font, int Width, int Height)
    {
        canvas.Clear(SKColors.White);
        this.canvas = canvas;
        centerPoint = new SKPoint(Width / 2, Height / 2);
        //球
        if (Ball == null)
        {
            Ball = new Ball()
            {
                X = 50,
                Y = Height - 50,
                Radius = 30
            };
        }
        //箱子
        var boxX = Width - 170;
        var boxY = Height - 80;
        if (Box.X == 0)
        {
            Box = new Rect(boxX, boxY, 120, 70);
        }
        else
        {
            if (Box.X != boxX && Box.Y != boxY)
            {
                Box.X = boxX;
                Box.Y = boxY;
            }
        }

        if (bools.Count >= ALLCount)
        {
            IsOver = true;
        }

        if (!IsOver)
        {
            if (IsMoving)
            {
                BallMove(Width, Height);
            }
            else
            {
                DrawLine();
            }

            //彈球
            DrawCircle(canvas, Ball);
            //矩形
            DrawRect(canvas, Box);

            //計(jì)分
            using var paint1 = new SKPaint
            {
                Color = SKColors.Blue,
                IsAntialias = true,
                Typeface = Font,
                TextSize = 24
            };
            string count = $"總次數(shù):{ALLCount} 剩余次數(shù):{ALLCount - bools.Count} 投中次數(shù):{bools.Count(t => t)}";
            canvas.DrawText(count, 100, 20, paint1);
        }
        else
        {
            SKColor sKColor = SKColors.Blue;
            //計(jì)分
            var SuccessCount = bools.Count(t => t);
            string count = "";
            switch (SuccessCount)
            {
                case 0:
                    {
                        count = $"太糗了吧,一個(gè)都沒(méi)投中!";
                        sKColor = SKColors.Black;
                    }
                    break;
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    {
                        count = $"你才投中:{SuccessCount}次,繼續(xù)努力!";
                        sKColor = SKColors.Blue;
                    }
                    break;
                case 6:
                case 7:
                case 8:
                case 9:
                    {
                        count = $"恭喜 投中:{SuccessCount}次!!!";
                        sKColor = SKColors.YellowGreen;
                    }
                    break;
                case 10: { count = $"全部投中,你太厲害了!";
                        sKColor = SKColors.Red;
                    } break;
            }
            using var paint1 = new SKPaint
            {
                Color = sKColor,
                IsAntialias = true,
                Typeface = Font,
                TextSize = 48
            };
            var fontCenter = paint1.MeasureText(count);
            canvas.DrawText(count, centerPoint.X - fontCenter / 2, centerPoint.Y, paint1);
        }
        using var paint = new SKPaint
        {
            Color = SKColors.Blue,
            IsAntialias = true,
            Typeface = Font,
            TextSize = 24
        };
        string by = $"by 藍(lán)創(chuàng)精英團(tuán)隊(duì)";
        canvas.DrawText(by, 600, 20, paint);
    }
    /// <summary>
    /// 畫(huà)一個(gè)圓
    /// </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);
    }
    /// <summary>
    /// 畫(huà)一個(gè)矩形
    /// </summary>
    public void DrawRect(SKCanvas canvas, Rect box)
    {
        using var paint = new SKPaint
        {
            Color = SKColors.Green,
            Style = SKPaintStyle.Fill,
            IsAntialias = true,
            StrokeWidth = 2
        };
        canvas.DrawRect((float)box.X, (float)box.Y, (float)box.Width, (float)box.Height, paint);
    }
    /// <summary>
    /// 劃線
    /// </summary>
    public void DrawLine()
    {
        //劃線
        using var LinePaint = new SKPaint
        {
            Color = SKColors.Red,
            Style = SKPaintStyle.Fill,
            StrokeWidth = 2,
            IsStroke = true,
            StrokeCap = SKStrokeCap.Round,
            IsAntialias = true
        };
        var path = new SKPath();
        path.MoveTo((float)CurrentMousePoint.X, (float)CurrentMousePoint.Y);
        path.LineTo((float)Ball.X, (float)Ball.Y);
        path.Close();
        canvas.DrawPath(path, LinePaint);
    }
    public void BallMove(int Width, int Height)
    {
        Ball.VX *= F;
        Ball.VY *= F;
        Ball.VY += G;

        Ball.X += Ball.VX;
        Ball.Y += Ball.VY;

        var hit = CheckHit();
        // 邊界處理和碰撞檢測(cè)
        if (hit || Ball.X - Ball.Radius > Width || Ball.X + Ball.Radius < 0 || Ball.Y - Ball.Radius > Height || Ball.Y + Ball.Radius < 0)
        {
            bools.Add(hit);
            IsMoving = false;
            Ball.X = 50;
            Ball.Y = Height - 50;
        }

        lastPoint.X = (float)Ball.X;
        lastPoint.Y = (float)Ball.Y;
    }
    public bool CheckHit()
    {
        var k1 = (Ball.Y - lastPoint.Y) / (Ball.X - lastPoint.X);
        var b1 = lastPoint.Y - k1 * lastPoint.X;
        var k2 = 0;
        var b2 = Ball.Y;
        var cx = (b2 - b1) / (k1 - k2);
        var cy = k1 * cx + b1;
        if (cx - Ball.Radius / 2 > Box.X && cx + Ball.Radius / 2 < Box.X + Box.Width && Ball.Y - Ball.Radius > Box.Y)
        {
            return true;
        }
        return false;
    }
    public void MouseMove(SKPoint sKPoint)
    {
        CurrentMousePoint = sKPoint;
    }
    public void MouseDown(SKPoint sKPoint)
    {
        CurrentMousePoint = sKPoint;
    }
    public void MouseUp(SKPoint sKPoint)
    {
        if (bools.Count < ALLCount)
        {
            IsMoving = true;
            Ball.VX = (sKPoint.X - Ball.X) * Easing;
            Ball.VY = (sKPoint.Y - Ball.Y) * Easing;
            lastPoint.X = (float)Ball.X;
            lastPoint.Y = (float)Ball.Y;
        }
    }
}

效果如下

還不錯(cuò),得了7分,當(dāng)然,我也可以得10分的,不過(guò),還好了。

總結(jié)

這個(gè)特效的案例重點(diǎn)是光線投影法碰撞檢測(cè),同時(shí)又對(duì)其增加了游戲的屬性,雖然東西都很簡(jiǎn)單,但是作為一個(gè)雛形來(lái)講也是不錯(cuò)的。

SkiaSharp 基礎(chǔ)系列算是告一段落了,基礎(chǔ)知識(shí)相關(guān)暫時(shí)都已經(jīng)有了一個(gè)深度的了解,對(duì)于它的基礎(chǔ)應(yīng)用已經(jīng)有一個(gè)不錯(cuò)的認(rèn)識(shí)了,那么,基于它的應(yīng)用應(yīng)該也會(huì)多起來(lái),我這邊主要參考Avalonia的內(nèi)部SkiaSharp使用原理,當(dāng)然,用法肯定不局限的。

代碼地址

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

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

到此這篇關(guān)于WPF+SkiaSharp實(shí)現(xiàn)自繪投籃小游戲的文章就介紹到這了,更多相關(guān)WPF SkiaSharp投籃游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中async和await的深入分析

    C#中async和await的深入分析

    Async/Await是C# 5引入的關(guān)鍵字,用以提高用戶界面響應(yīng)能力和對(duì)Web資源的訪問(wèn)能力,同時(shí)它使異步代碼的編寫(xiě)變得更加容易,下面這篇文章主要給大家介紹了關(guān)于C#中async和await的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C#開(kāi)發(fā)Windows UWP系列之布局面板RelativePanel

    C#開(kāi)發(fā)Windows UWP系列之布局面板RelativePanel

    這篇文章介紹了C#開(kāi)發(fā)Windows UWP系列之布局面板RelativePanel,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C#聯(lián)合VisionPro實(shí)現(xiàn)TCP/IP通信詳解

    C#聯(lián)合VisionPro實(shí)現(xiàn)TCP/IP通信詳解

    TCP/IP(傳輸控制協(xié)議/互聯(lián)網(wǎng)協(xié)議)是一組用于在網(wǎng)絡(luò)上進(jìn)行通信的通信協(xié)議,本文主要為大家詳細(xì)介紹了C#如何聯(lián)合VisionPro實(shí)現(xiàn)TCP/IP通信,希望對(duì)大家有所幫助
    2024-02-02
  • C# 使用PictureBox實(shí)現(xiàn)圖片按鈕控件的示例步驟

    C# 使用PictureBox實(shí)現(xiàn)圖片按鈕控件的示例步驟

    這篇文章主要介紹了C# 使用PictureBox實(shí)現(xiàn)圖片按鈕控件的示例步驟,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • 利用C#守護(hù)Python進(jìn)程的方法

    利用C#守護(hù)Python進(jìn)程的方法

    這篇文章主要給大家介紹了關(guān)于如何利用C#守護(hù)Python進(jìn)程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能

    使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能

    這篇文章主要為大家介紹了使用快捷鍵在Unity中快速鎖定和解鎖Inspector右上角的鎖功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • C#中單例模式的三種寫(xiě)法示例

    C#中單例模式的三種寫(xiě)法示例

    這篇文章主要介紹了C#中單例模式的三種寫(xiě)法示例,本文分別給出代碼實(shí)例,需要的朋友可以參考下
    2015-06-06
  • C# SMTP發(fā)送郵件的示例

    C# SMTP發(fā)送郵件的示例

    這篇文章主要介紹了C# SMTP發(fā)送郵件的示例,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2020-12-12
  • 利用C#實(shí)現(xiàn)AOP常見(jiàn)的幾種方法詳解

    利用C#實(shí)現(xiàn)AOP常見(jiàn)的幾種方法詳解

    AOP面向切面編程(Aspect Oriented Programming),是通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。下面這篇文章主要給大家介紹了關(guān)于利用C#實(shí)現(xiàn)AOP常見(jiàn)的幾種方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-09-09
  • .Net?Core以windows服務(wù)方式部署

    .Net?Core以windows服務(wù)方式部署

    這篇文章介紹了.Net?Core以windows服務(wù)方式部署,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01

最新評(píng)論