我创建了一个平铺匹配游戏,玩家将平铺拖动到平铺支架上,如果放置了正确的平铺,则获得积分。请参阅下图以供参考:
我正在使用ScatterView控件,从Microsoft.Surface.Presentation作为一个板来保存我的tile,以及ScatterViewItems,作为tile本身。
我希望能够将ScatterViewItems放到持有者身上,并为相应的持有者评估它是否可以接受放在它上面的瓷砖。
我已经设法获得了我需要的大量信息,但是我从我的瓷砖持有者那里获得的变换界限信息是否有偏差?
我正在使用touch up事件,而rect包含/ intersectswith方法,但是我得到的关于tile holder的结果不正确。虽然许多结果很接近,但它们都略有不同。我试过画我的作品'到画布,但它显示正确的点和尺寸。
我最初正在旋转我的一些控件,因为我需要它们沿着电路板的侧面,然而停止了这一点,因为它被认为是责备,但结果仍然是错误的。您会注意到(如果您获得解决方案zip),在某些持有者上,边界将无法正确注册,而有时当没有超过持有者(就在附近)时它会。我认为我使用的矩形界限不正确,但我看不出错误!真的很感激任何帮助。
这是指向解决方案拉链的链接(VS2015):project solution as zip
如果您愿意,可以使用主要代码:
using Microsoft.Surface.Presentation.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace TestingSVI_Intersection
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private static Action EmptyDelegate = delegate () { };
StackPanel[] stacks = new StackPanel[4];
Vector tileSize = new Vector(60, 80);
Vector holderSize = new Vector(0, 0);
Vector gameGridSize = new Vector(0, 0);
int numberOfLetters = 5;
public MainWindow()
{
InitializeComponent();
}
private void Svi_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
ScatterViewItem svi = e.Source as ScatterViewItem;
Point p1 = svi.TransformToAncestor(MiddleGrid).Transform(new Point(0, 0));
Rect r1 = new Rect(p1.X, p1.Y, svi.ActualWidth, svi.ActualHeight);
Console.WriteLine($"SVI at: {svi.ActualCenter}");
Rectangle rectangle;
foreach (StackPanel panel in stacks)
{
foreach (UserControl holder in panel.Children)
{
Point p2 = holder.TransformToAncestor(MiddleGrid).Transform(new Point(0, 0));
Rect r2 = new Rect(p2.X, p2.Y, holder.ActualWidth, holder.ActualHeight);
rectangle = new Rectangle();
rectangle.Width = holder.Width;
rectangle.Height = holder.Height;
Canvas.SetLeft(rectangle, p2.X);
Canvas.SetTop(rectangle, p2.Y);
rectangle.Stroke = new SolidColorBrush(Colors.SpringGreen);
rectangle.StrokeThickness = 1;
canvasMe.Children.Add(rectangle);
if (r2.IntersectsWith(r1) == true)
{
if (r2.Contains(p1))
{
Console.WriteLine($"Intersection at: {holder.Name}");
}
}
}
}
}
private void IntersectionFound(ScatterViewItem svi, UserControl uC)
{
}
//private void Svi_PreviewTouchUp(object sender, TouchEventArgs e)
//{
// ScatterViewItem svi = e.Source as ScatterViewItem;
// Point p1 = svi.TransformToAncestor(mainGrid).Transform(new Point(0, 0));
// Rect r1 = new Rect(p1.X, p1.Y, svi.ActualWidth, svi.ActualHeight);
// Console.WriteLine($"SVI at: {svi.ActualCenter}");
// foreach (StackPanel panel in stacks)
// {
// foreach (UserControl holder in panel.Children)
// {
// Point p2 = holder.TransformToAncestor(mainGrid).Transform(new Point(0, 0));
// Rect r2 = new Rect(p2.X, p2.Y, holder.ActualWidth, holder.ActualHeight);
// Console.WriteLine($"Checked: {holder.Name} at centre: ({p2.X + holder.Width / 2}, {p2.Y + holder.Height / 2})");
// //if (r1.IntersectsWith(r2) == true)
// //{
// // Console.WriteLine($"Intersection at: {holder.Name}");
// //}
// if (r2.Contains(r1) == true)
// {
// Console.WriteLine($"Intersection at: {holder.Name}");
// }
// }
// }
//}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (stacks[3] != null)
{
foreach (StackPanel panel in stacks)
{
panel.Children.Clear();
}
canvasMe.Children.Clear();
scatterView.Items.Clear();
}
gameGridSize.X = MiddleGrid.ActualWidth;
gameGridSize.Y = MiddleGrid.ActualHeight;
holderSize.X = gameGridSize.X * 0.10f;
holderSize.Y = gameGridSize.Y * 0.15f;
stacks[0] = letterHolders1;
stacks[1] = letterHolders2;
stacks[2] = letterHolders3;
stacks[3] = letterHolders4;
int count = 0;
foreach (StackPanel panel in stacks)
{
for (int i = 0; i < numberOfLetters; i++)
{
UserControl uC = new UserControl
{
Width = holderSize.X,
Height = holderSize.Y,
Background = new SolidColorBrush(Colors.Black),
BorderThickness = new Thickness(1),
BorderBrush = new SolidColorBrush(Colors.Yellow),
Name = $"UC_{count.ToString()}"
};
count++;
if (panel == stacks[1] || panel == stacks[2])
{
//uC.LayoutTransform = new RotateTransform(90);
uC.Width = holderSize.Y;
uC.Height = holderSize.X;
}
panel.Children.Add(uC);
}
}
MiddleGrid.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
Console.WriteLine($"Stack 2: ({letterHolders2.ActualWidth}, {letterHolders2.ActualHeight})");
holderSize.X = letterHolders2.ActualHeight / numberOfLetters;
tileSize.X = holderSize.X * 0.8f;
tileSize.Y = holderSize.Y * 0.8f;
foreach (StackPanel panel in stacks)
{
foreach (UserControl control in panel.Children)
{
control.Width = holderSize.X;
control.Height = holderSize.Y;
if (panel == stacks[1] || panel == stacks[2])
{
control.Width = holderSize.Y;
control.Height = holderSize.X;
}
}
}
for (int i = 0; i < 10; i++)
{
ScatterViewItem svi = new ScatterViewItem
{
Width = tileSize.X,
MinWidth = tileSize.X,
MaxWidth = tileSize.X,
Height = tileSize.Y,
MinHeight = tileSize.Y,
MaxHeight = tileSize.Y,
Background = new SolidColorBrush(Colors.Red),
};
//svi.PreviewTouchUp += Svi_PreviewTouchUp;
svi.PreviewMouseUp += Svi_PreviewMouseUp;
scatterView.Items.Add(svi);
}
}
}
}
它对应的XAML:
<Window x:Class="TestingSVI_Intersection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="http://schemas.microsoft.com/surface/2008"
xmlns:local="clr-namespace:TestingSVI_Intersection"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid x:Name="mainGrid">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Grid Background="Black" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="64"/>
<RowDefinition/>
<RowDefinition Height="64"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Gray"/>
<Grid Grid.Row="1"/>
<Grid Grid.Row="2" Background="Gray"/>
</Grid>
<Grid Background="Black" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="64"/>
<RowDefinition/>
<RowDefinition Height="64"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Gray"/>
<Grid Grid.Row="1">
<Button x:Name="startButton" Content="Start" Height="60" VerticalAlignment="Top" Background="Blue" Foreground="White" Click="Button_Click"/>
</Grid>
<Grid Grid.Row="2" Background="Gray"/>
</Grid>
<Grid Grid.Column="1" Grid.Row="1" x:Name="MiddleGrid">
<Grid x:Name="GameGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.6*"/>
<ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.2*"/>
<RowDefinition Height="0.6*"/>
<RowDefinition Height="0.2*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="letterHolders1" Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top">
</StackPanel>
<StackPanel x:Name="letterHolders2" Orientation="Vertical" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center">
</StackPanel>
<StackPanel x:Name="letterHolders3" Orientation="Vertical" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center">
</StackPanel>
<StackPanel x:Name="letterHolders4" Orientation="Horizontal" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Bottom">
</StackPanel>
</Grid>
<s:ScatterView x:Name="scatterView">
</s:ScatterView>
<Canvas x:Name="canvasMe" IsHitTestVisible="False"/>
</Grid>
</Grid>
</Grid>
</Window>