返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >WPF+SkiaSharp实现自绘投篮小游戏
  • 141
分享到

WPF+SkiaSharp实现自绘投篮小游戏

WPF SkiaSharp投篮游戏WPF 投篮游戏WPF 游戏 2022-11-13 14:11:20 141人浏览 薄情痞子
摘要

目录投篮小游戏WPF 和 SkiaSharp弹球实体代码 (Ball.cs)粒子花园核心类 (ParticleGarden.cs)效果如下总结代码地址投篮小游戏 规则,点击投篮目标点

投篮小游戏

规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩形,直接是按照碰撞检测来的,碰到就算进去了,对其增加了一个分数统计等功能。

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

效果如下

还不错,得了7分,当然,我也可以得10分的,不过,还好了。

总结

这个特效的案例重点是光线投影法碰撞检测,同时又对其增加了游戏的属性,虽然东西都很简单,但是作为一个雏形来讲也是不错的。

SkiaSharp 基础系列算是告一段落了,基础知识相关暂时都已经有了一个深度的了解,对于它的基础应用已经有一个不错的认识了,那么,基于它的应用应该也会多起来,我这边主要参考Avalonia的内部SkiaSharp使用原理,当然,用法肯定不局限的。

代码地址

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

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

到此这篇关于WPF+SkiaSharp实现自绘投篮小游戏的文章就介绍到这了,更多相关WPF SkiaSharp投篮游戏内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: WPF+SkiaSharp实现自绘投篮小游戏

本文链接: https://lsjlt.com/news/171891.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • WPF+SkiaSharp实现自绘投篮小游戏
    目录投篮小游戏Wpf 和 SkiaSharp弹球实体代码 (Ball.cs)粒子花园核心类 (ParticleGarden.cs)效果如下总结代码地址投篮小游戏 规则,点击投篮目标点...
    99+
    2022-11-13
    WPF SkiaSharp投篮游戏 WPF 投篮游戏 WPF 游戏
  • WPF+SkiaSharp实现自绘拖曳小球
    目录拖曳小球Wpf 和 SkiaSharp实现代码效果如下拖曳小球 WPF的拖曳效果,基本配置一下,就可以了,但是自绘的话,就得自己控制,按键点击,按键移动和按键松开的事件,与其配合...
    99+
    2024-04-02
  • WPF+SkiaSharp实现自绘弹幕效果
    SkiaSharp 自绘弹幕效果 框架使用.NET60; Visual Studio 2022; 项目使用 MIT 开源许可协议; 接着上一篇 WPF 弹幕 上期...
    99+
    2024-04-02
  • 你喜欢篮球吗?Python实现篮球游戏
    一、前言 准备编写一个篮球游戏,运动员带球跑,跳起投篮。在每帧图片中包括运动员和篮球,使用多帧图片,实现运动员运球跑动的效果。运动员运球跑动作每帧图形的宽和高可能不同,例如,跨一大步...
    99+
    2024-04-02
  • Python如何实现篮球游戏
    这篇文章给大家分享的是有关Python如何实现篮球游戏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、前言准备编写一个篮球游戏,运动员带球跑,跳起投篮。在每帧图片中包括运动员和篮球,使用多帧图片,实现运动员运球...
    99+
    2023-06-15
  • PythonPygame实战之趣味篮球游戏的实现
    目录导语一、环境安装二、代码展示1)游戏界面文字2)主程序三、效果展示1)游戏玩家一2)游戏玩家二3)随机投篮导语 贪玩的我~终于回来了! 今日过后,日常更新—&mdas...
    99+
    2024-04-02
  • 【pygame游戏】用Python实现一个蔡徐坤大战篮球的小游戏,可还行?【附源码】
    Python制作坤坤打篮球小游戏 序言准备工作开发环境 效果预览开始界面游戏规则结束游戏 代码实现 序言 话说在前面,我不是小黑子~ 我是超级大黑子😏 ...
    99+
    2023-09-02
    python pygame 游戏 篮球
  • 基于WPF实现经典纸牌游戏
    目录1 纸牌类2 布局3 初始化4 事件点击牌堆拖动牌的去留1 纸牌类 之所以产生这个无聊至极的念头,是因为发现Unicode中竟然有这种字符。。。 这就意味着不用任何资源就可以实...
    99+
    2023-02-27
    WPF实现纸牌游戏 WPF纸牌游戏 WPF游戏
  • C++实现投骰子的随机游戏
    本文实例为大家分享了C++实现投骰子的随机游戏的具体代码,供大家参考,具体内容如下 每个骰子有六面,点数分别为1、2、3、4、5、6。游戏者在程序开始时输入一个无符号整数,作为产生随...
    99+
    2024-04-02
  • 基于Python实现自制拼图小游戏
    咱们Python 集中营有一个专题就是分享一些有意思的东西,今天大概看了一下pygame的这个非标准库就想着使用它来做个小游戏-拼图。 通过加入自己定义的图片,对这个图片完成一定数...
    99+
    2022-11-13
    Python拼图游戏 Python拼图
  • android自定义view实现推箱子小游戏
    本文实例为大家分享了android推箱子游戏的具体实现代码,供大家参考,具体内容如下 自定义view: package com.jisai.materialdesignd...
    99+
    2022-06-06
    小游戏 view 推箱子 Android
  • 基于WPF如何实现经典纸牌游戏
    这篇“基于WPF如何实现经典纸牌游戏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于WPF如何实现经典纸牌游戏”文章吧。1...
    99+
    2023-07-05
  • python实现21点小游戏
    用python实现21点小游戏,供大家参考,具体内容如下 from random import shuffle import random import numpy as np from sys import...
    99+
    2022-06-02
    python 21点游戏
  • Java实现数独小游戏
    本文实例为大家分享了Java实现数独小游戏的具体代码,供大家参考,具体内容如下 题目要求: 制作一个数独游戏。数据游戏拼图由一个3*3的九宫格组成,每个格式又分成一个小九宫格,共九九...
    99+
    2024-04-02
  • java实现弹球小游戏
    GUI实现弹球小游戏,供大家参考,具体内容如下 先看一下游戏效果图。 一个简单的Demo。也比较简单,新手试着做一做完善改进。 源代码 import Com.Style.Fo...
    99+
    2024-04-02
  • Python实现24点小游戏
    本文实例为大家分享了Python实现24点小游戏的具体代码,供大家参考,具体内容如下 玩法:通过加减乘除操作,小学生都没问题的。 源码分享: import os import ...
    99+
    2024-04-02
  • Python实现滑雪小游戏
    本文实例为大家分享了Python实现滑雪小游戏的具体代码,供大家参考,具体内容如下 源码分享: import sys import cfg import pygame imp...
    99+
    2024-04-02
  • iOS实现拼图小游戏
    本文实例为大家分享了iOS实现拼图小游戏的具体代码,供大家参考,具体内容如下 首先找到这8张图片,还需要一张空白的图片,自己随便剪一张吧。 定义三个属性:button可变数组,图片...
    99+
    2024-04-02
  • jQuery实现扫雷小游戏
    本文实例为大家分享了jQuery实现扫雷小游戏的具体代码,供大家参考,具体内容如下 扫雷小游戏实现思路: 设计为9*9简单面板,每次随机生成10颗雷,然后计算每颗雷周围八个位置上每个...
    99+
    2024-04-02
  • Java实现飞机小游戏
    本文实例为大家分享了Java实现飞机小游戏的具体代码,供大家参考,具体内容如下 该小游戏使用java语言实现,使用工具idea。 共写9个类 Constant;Explode;Gam...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作