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>
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 和诸如此类的操作,然后始终使用简单的数学运算得到基本颜色。
我正在学习 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>
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 和诸如此类的操作,然后始终使用简单的数学运算得到基本颜色。