Skiasharp 旋转轮盘游戏。两物勾结

Skiasharp spin the wheel game . two object collusion

我正在学习 skiasharp 并玩转盘游戏。 我成功地把一个分割的圆圈分成六个不同颜色的部分,并让它旋转 10 秒。

我现在想做什么,但我没有做到,也许我可以得到你的看法和意见。 我希望当圆圈停止旋转时,选择一种颜色,让别针位于其中。

我试图搜索 skiasharp collusion,但没有成功。

这是我的代码。

我的 spin.cs :

public partial class Spin : ContentPage
    {
        Stopwatch stopwatch = new Stopwatch();

        bool _pageIsActive;
        float _degrees;

        class ChartData
        {
            public ChartData(int value, SKColor color)
            {
                Value = value;
                Color = color;
            }

            public int Value { private set; get; }

            public SKColor Color { private set; get; }
        }

        ChartData[] chartData =
        {
            new ChartData(10, SKColors.Red),
            new ChartData(10, SKColors.Green),
            new ChartData(10, SKColors.Blue),
            new ChartData(10, SKColors.Magenta),
            new ChartData(10, SKColors.Cyan),
            new ChartData(10, SKColors.Brown)
        };
        public Spin()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            _pageIsActive = true;
        }
        protected override void OnDisappearing()
        {
            base.OnDisappearing();
            _pageIsActive = false;
        }
        async Task AnimationLoop()
        {
            stopwatch.Reset();
            stopwatch.Start();

            while (_pageIsActive && stopwatch.Elapsed < TimeSpan.FromSeconds(10))
            {
                skiaView.InvalidateSurface();
                await Task.Delay(TimeSpan.FromSeconds(1.0 / 90));
            }
            stopwatch.Stop();

        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            IncrementDegrees();

            SKImageInfo info = args.Info;
            SKSurface surface = args.Surface;
            SKCanvas canvas = surface.Canvas;

            var x1 = info.Width / 6;
            var x2 = info.Width / 3 + x1;
            var x3 = info.Width / 3 * 2 + x1;
            var y = info.Height / 2;
            int _squareWidth = Math.Min(info.Width, info.Height) / 10;

            canvas.Clear();

            int totalValues = 0;

            foreach (ChartData item in chartData)
            {
                totalValues += item.Value;
            }

            SKPoint center = new SKPoint(info.Width / 2, info.Height / 2);
            float explodeOffset = 50;
            float radius = Math.Min(info.Width / 2, info.Height / 2) - 2 * explodeOffset;
            SKRect rect = new SKRect(center.X - radius, center.Y - radius,
                                     center.X + radius, center.Y + radius);

            float startAngle = 0;

            foreach (ChartData item in chartData)
            {
                float sweepAngle = 360f * item.Value / totalValues;

                using (SKPath path = new SKPath())
                using (SKPaint fillPaint = new SKPaint())
                using (SKPaint outlinePaint = new SKPaint())
                using (var path3 = new SKPath())
                {
                    path.MoveTo(center);
                    path.ArcTo(rect, startAngle, sweepAngle, false);
                    path.Close();

                    fillPaint.Style = SKPaintStyle.Fill;
                    fillPaint.Color = item.Color;

                    outlinePaint.Style = SKPaintStyle.Stroke;
                    outlinePaint.StrokeWidth = 5;
                    outlinePaint.Color = SKColors.Black;

                    canvas.Save();

                    // Fill and stroke the path
                    //canvas.DrawPath(path, fillPaint);
                   // canvas.DrawPath(path, outlinePaint);


                    var cx3 = x3 - _squareWidth / 2;
                    var cy3 = y + _squareWidth / 2;
                    path3.MoveTo(cx3, cy3);
                    path3.LineTo(cx3 + _squareWidth, cy3);
                    path3.LineTo(cx3 + _squareWidth, cy3 - _squareWidth);
                    path3.LineTo(cx3, cy3 - _squareWidth);
                    path3.LineTo(cx3, cy3);
                    DrawRotatedWithMatrices(canvas, path, fillPaint, outlinePaint, _degrees, (int)center.X, y);
                    canvas.Restore();


                }

                startAngle += sweepAngle;
            }
            canvas.RotateDegrees(90);
        }
        private void IncrementDegrees()
        {
            _degrees += 3.5f;

            if (_degrees >= 360)
            {
                _degrees = 0;
            }
        }
        void DrawRotatedWithMatrices(SKCanvas canvas, SKPath path, SKPaint fill,SKPaint outline ,float degrees, int cx, int cy)
        {
            var result = SKMatrix.MakeIdentity();
            var translate = SKMatrix.MakeTranslation(-cx, -cy);
            var rotate = SKMatrix.MakeRotationDegrees(degrees);
            var translate2 = SKMatrix.MakeTranslation(cx, cy);

            SKMatrix.PostConcat(ref result, translate);
            SKMatrix.PostConcat(ref result, rotate);
            SKMatrix.PostConcat(ref result, translate2);

            path.Transform(result);
            canvas.DrawPath(path, fill);
            canvas.DrawPath(path, outline);
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            _pageIsActive = true;

            AnimationLoop();

        }

        private void Button_Clicked_1(object sender, EventArgs e)
        {
            _pageIsActive = false;

        }
    }

我的spin.xaml

<StackLayout x:Name="viewx">
                <skia:SKCanvasView x:Name="skiaView" PaintSurface="OnCanvasViewPaintSurface" HeightRequest="500" WidthRequest="500"/>

            </StackLayout>

使用SKPath.Contains

Returns true if the point (x, y) is contained by the path, taking into account the FillType.

你也可以不关心你的案例的实际图纸。由于每个片段都是平等的,所以只做所有的动画和事情。然后,当旋转停止时,检查旋转并使用基本除法来获得颜色。

例如,您有 6 个细分:

ChartData[] chartData =
{
    new ChartData(10, SKColors.Red),
    new ChartData(10, SKColors.Green),
    new ChartData(10, SKColors.Blue),
    new ChartData(10, SKColors.Magenta),
    new ChartData(10, SKColors.Cyan),
    new ChartData(10, SKColors.Brown)
};

做个基础的(伪代码):

var segment = (rotationInDegrees / 360f) * chartData.Length;
var data = chartData[segement];
var color = data.Color;

这样,您可以对 UI 进行各种奇特的 filters/gradients 和诸如此类的操作,然后始终使用简单的数学运算得到基本颜色。