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;?}
}

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

///?<summary>
///?光線投影法碰撞檢測
///?投籃小游戲
///?</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);//計分using?var?paint1?=?new?SKPaint{Color?=?SKColors.Blue,IsAntialias?=?true,Typeface?=?Font,TextSize?=?24};string?count?=?$"總次數:{ALLCount}?剩余次數:{ALLCount?-?bools.Count}?投中次數:{bools.Count(t?=>?t)}";canvas.DrawText(count,?100,?20,?paint1);}else{SKColor?sKColor?=?SKColors.Blue;//計分var?SuccessCount?=?bools.Count(t?=>?t);string?count?=?"";switch?(SuccessCount){case?0:{count?=?$"太糗了吧,一個都沒投中!";sKColor?=?SKColors.Black;}break;case?1:case?2:case?3:case?4:case?5:{count?=?$"你才投中:{SuccessCount}次,繼續努力!";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?藍創精英團隊";canvas.DrawText(by,?600,?20,?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);}///?<summary>///?畫一個矩形///?</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();//?邊界處理和碰撞檢測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;}}
}

效果如下:

8b901f1784ad842705fca38a5796be1d.gif

還不錯,得了7分,當然,我也可以得10分的,不過,還好了。

總結

這個特效的案例重點是光線投影法碰撞檢測,同時又對其增加了游戲的屬性,雖然東西都很簡單,但是作為一個雛形來講也是不錯的。

SkiaSharp 基礎系列算是告一段落了,基礎知識相關暫時都已經有了一個深度的了解,對于它的基礎應用已經有一個不錯的認識了,那么,基于它的應用應該也會多起來,我這邊主要參考Avalonia的內部SkiaSharp使用原理,當然,用法肯定不局限的。

代碼地址

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

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

一鍵三連呦!,感謝大佬的支持,您的支持就是我的動力!

版權

藍創精英團隊(公眾號同名,CSDN 同名,CNBlogs 同名)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/283986.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/283986.shtml
英文地址,請注明出處:http://en.pswp.cn/news/283986.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

zuul集成ribbon完成服務通信和負載均衡

目錄 Zuul2服務通信 超時相關 默認超時配置 自定義超時配置 負載均衡 Zuul2服務通信 描述&#xff1a;zuul2通過Ribbon完成客戶端負載均衡以及與服務器群集進行通信。 zuul2的通信是集成Ribbon實現的&#xff0c;在Origin中集成Ribbon基本配置&#xff08;例如IClientCo…

時任上海來伊份互聯網事業群總裁王戈鈞 :傳統企業(線上+線下)移動互聯網改造...

2017年12月22日-23日&#xff0c;第13屆信息化領袖峰會暨2017中國數字化貢獻人物頒獎盛典在上海盛大開幕。本次峰會由上海市經濟和信息化委員會指導&#xff0c;上海市國有資產信息中心、上海市計算機用戶協會、上海市信息服務業行業協會、上海大數據聯盟、上海市高等教育學會支…

Linux系統時間\硬件時間(date、tzselect、clock、hwclock、ntpdate)

1、系統時間和硬件時間 在Linux中有硬件時鐘與系統時鐘兩種時鐘。硬件時鐘是指主機板上的時鐘設備&#xff0c;也就是通常可在BIOS畫面設定的時鐘。系統時鐘則是指kernel中的時鐘。所有Linux相關指令與函數都是讀取系統時鐘的設定。因為存在兩種不同的時鐘&#xff0c;那么它們…

C#------如何判斷輸入的是否為純數字

private void Btn_OK_Click(object sender, EventArgs e){IDormitoryAdminCardService aservice new DormitoryAdminCardService();string text this.CardNoEdit.Text;//判斷是否輸入的是純數字string pattern "^[0-9]*$";Regex regex new Regex(pattern);if (re…

【.NET6+Modbus】Modbus TCP協議解析、仿真環境以及基于.NET實現基礎通信

接下來的內容&#xff0c;我會以從頭開發一個簡單的基于modbus tcp通信的案例&#xff0c;來實現一個基礎的通信功能。有關環境&#xff1a;開發環境&#xff1a;VS 2022企業版運行環境&#xff1a;Win 10 專業版.NET 環境版本&#xff1a;.NET 6【備注】 源碼在文末 1、新建一…

源碼深度剖析Eureka與Ribbon服務發現原理

本文基于 spring cloud dalston&#xff0c;同時文章較長&#xff0c;請選擇舒服姿勢進行閱讀。 Eureka 與 Ribbon 是什么&#xff1f;和服務發現什么關系&#xff1f; Eureka 與 Ribbon 都是 Netflix 提供的微服務組件&#xff0c;分別用于服務注冊與發現、負載均衡。同時&a…

3月6日云棲精選夜讀:如何實現32.5萬筆/秒的交易峰值?阿里交易系統TMF2.0技術揭秘...

交易平臺遇到的挑戰 2017雙11&#xff0c;交易峰值達到了32.5萬筆/秒&#xff0c;這給整個交易系統帶來了非常大的挑戰。 一方面&#xff0c;系統需要支撐全集團幾十個事業部的所有交易類需求&#xff1a;要考慮如何能更快響應需求、加快發布周期&#xff1b;如何能為新小業務提…

std的find和reverse_iterator聯合使用

上代碼&#xff1a; // test2013.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include<iostream> #include<vector> #include<map> #include<string> using namespace …

論如何提升學習的能力

為啥要學習如果有一件事情是能改變你自己的&#xff0c;我想這件事情必然就是學習&#xff0c;我的人生重要的轉折點也是從學習這件事情始發的&#xff0c;那么&#xff0c;我們就從這里開始。學習不僅僅是為了找到答案&#xff0c;而是為了找到方法&#xff0c;找到一個可以找…

linux下svn常用指令

windows下的TortoiseSVN是資源管理器的一個插件&#xff0c;以覆蓋圖標表示文件狀態&#xff0c;幾乎所以命令都有圖形界面支持&#xff0c;比較好用&#xff0c;這里就不多說。主要說說linux下svn的使用&#xff0c;因為linux下大部分的操作都是通過命令行來進行&#xff0c;所…

CSS布局解決方案(終結版)

前端布局非常重要的一環就是頁面框架的搭建&#xff0c;也是最基礎的一環。在頁面框架的搭建之中&#xff0c;又有居中布局、多列布局以及全局布局&#xff0c;今天我們就來總結總結前端干貨中的CSS布局。 居中布局 水平居中 1&#xff09;使用inline-blocktext-align&#xff…

基于ABP和Magicodes實現Excel導出操作

前端使用的vue-element-admin框架&#xff0c;后端使用ABP框架&#xff0c;Excel導出使用的Magicodes.IE.Excel.Abp庫。Excel導入和導出操作幾乎一樣&#xff0c;不再介紹。文本主要介紹Excel導出操作和過程中遇到的坑&#xff0c;主要是Excel文件導出后無法打開的問題。一.Mag…

消息模式在實際開發應用中的優勢

曾經.NET面試過程中經常問的一個問題是&#xff0c;如果程序集A&#xff0c;引用B &#xff0c;B 引用C&#xff0c;那么C怎么去訪問A中的方法呢。 這個問題初學.net可能一時想不出該咋處理&#xff0c;這涉及到循環引用問題。但有點經驗的可能就簡單了&#xff0c;通過委托的方…

微服務:注冊中心ZooKeeper、Eureka、Consul 、Nacos對比

前言 服務注冊中心本質上是為了解耦服務提供者和服務消費者。對于任何一個微服務&#xff0c;原則上都應存在或者支持多個提供者&#xff0c;這是由微服務的分布式屬性決定的。更進一步&#xff0c;為了支持彈性擴縮容特性&#xff0c;一個微服務的提供者的數量和分布往往是動…

MyBatis總結七:動態sql和sql片段

開發中&#xff0c;sql拼接很常見&#xff0c;所以說一下動態sql&#xff1a; 1if2chose,when,otherwise3where,set4foreach用法解析(現有一張users表 內有id username age 三個字段)&#xff1a; <!--查詢所有用戶&#xff0c;傳遞參數type&#xff0c;如果值為0&#xff0…

iOS - OC Copy 拷貝

前言 copy&#xff1a;需要先實現 NSCopying 協議&#xff0c;創建的是不可變副本。mutableCopy&#xff1a;需要實現 NSMutableCopying 協議&#xff0c;創建的是可變副本。淺拷貝&#xff1a;指針拷貝&#xff0c;源對象和副本指向的是同一個對象。對象的引用計數器 &#xf…

三.選擇結構(一)

1.if結構: if(條件){ 代碼塊 } 2.隨機產生數: int randon (int)(Math.random()*10); 3.多重if選擇結構: if(條件1){ 代碼塊1 }else if (條件2){ 代碼塊2 }else{ 代碼塊3 } 4.嵌套if選擇結構: if(條件1){ if(條件2){ 代碼塊1 }else{ 代碼塊2 } }else{ 代碼塊3 } 轉載于:https://…

為了高性能、超大規模的模型訓練,這個組合“出道”了

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;3分鐘)近年來&#xff0c;在大量數據上訓練的基于 transformer 的大規模深度學習模型在多項認知任務中取得了很好的成果&#xff0c;并且被使用到一些新產品和功能背后&#xff0c;進一步增強了人類的能力。在過去五年…

SVN就是這么簡單

什么是SVN SVN全稱&#xff1a;Subversion&#xff0c;是一個開放源代碼的版本控制系統 Svn是一種集中式文件版本管理系統。集中式代碼管理的核心是服務器&#xff0c;所有開發者在開始新一天的工作之前必須從服務器獲取代碼&#xff0c;然后開發&#xff0c;最后解決沖突&…

SpringCloud必會知識點大全

為什么要學習Spring Cloud 在項目開發中隨著業務越來越多&#xff0c;導致功能之間耦合性高、開發效率低、系統運行緩慢難以維護、不穩定。微服務 架構可以解決這些問題&#xff0c;而Spring Cloud是微服務架構最流行的實現. 1.微服務 微服務架構是使用一套小服務來開發單個應用…