c#-如何检测WPF中两个形状是否发生碰撞
发布时间:2022-06-20 05:57:27 244
相关标签: # flask
我有这段代码可以让用户在 WPF 的画布上绘制圆形、正方形或矩形。我需要这样做,这样一旦按下换档按钮,形状就会相互反弹。让形状从窗户的墙壁上反弹很容易,但我不知道如何让它们相互反弹。这是当前代码:
MainWindow.xaml.cs
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 ShapeAnimator
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
bool isFirstClick = true;
double x1, y1, x2, y2, x3, y3;
int shapeChoice =0;
Ellipse centerMark;
Ellipse tempCircle = new Ellipse();
Rectangle tempRect = new Rectangle();
List circles = new List();
List rectangles = new List();
public MainWindow()
{
InitializeComponent();
}
private void SquareButton_Click(object sender, RoutedEventArgs e)
{
shapeChoice = 1;
}
private void CircleButton_Click(object sender, RoutedEventArgs e)
{
shapeChoice = 0;
}
private void RectButton_Click(object sender, RoutedEventArgs e)
{
shapeChoice = 2;
}
private void ShiftButton_Click(object sender, RoutedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2);
timer.Tick += Timer_Tick;
timer.Start();
}
void Timer_Tick(object sender, EventArgs e)
{
Shift();
}
public void Shift()
{
foreach (Circle c in circles)
{
c.Shift(ShapeCanvas);
}
foreach (Rect r in rectangles)
{
r.Shift(ShapeCanvas);
}
}
private void ShapeCanvas_MouseUp(object sender, MouseButtonEventArgs e)
{
if (isFirstClick)
{
// This is the first click
// This is the CENTER coordinates (NOT the TOPLEFT)
x1 = e.GetPosition(this).X;
y1 = e.GetPosition(this).Y;
if(shapeChoice == 0)
{
centerMark = new Ellipse();
centerMark.Width = 4;
centerMark.Height = 4;
centerMark.Stroke = Brushes.Red;
ShapeCanvas.Children.Add(centerMark);
Canvas.SetLeft(centerMark, x1 - 2);
Canvas.SetTop(centerMark, y1 - 2);
ShapeCanvas.Children.Add(tempCircle);
}
else if (shapeChoice == 1)
{
ShapeCanvas.Children.Add(tempRect);
}
else if (shapeChoice == 2)
{
ShapeCanvas.Children.Add(tempRect);
}
}
else
{
// THis is the second click
double x2 = e.GetPosition(this).X;
double y2 = e.GetPosition(this).Y;
if (shapeChoice == 0)
{
double radius = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
Circle c = new Circle(x1, y1, radius);
c.Draw(ShapeCanvas);
circles.Add(c);
// remove the temp geometry
ShapeCanvas.Children.Remove(tempCircle);
ShapeCanvas.Children.Remove(centerMark);
}
else if(shapeChoice == 1)
{
double x3 = Math.Min(x1, x2);
double y3 = Math.Min(y1, y2);
double width = Math.Max(x1, x2) - x3;
double height = width;
Rect rec = new Rect(x3, y3, width, height);
rec.Draw(ShapeCanvas);
rectangles.Add(rec);
// remove the temp geometry
ShapeCanvas.Children.Remove(tempRect);
}
else if (shapeChoice == 2)
{
double x3 = Math.Min(x1, x2);
double y3 = Math.Min(y1, y2);
double width = Math.Max(x1, x2) - x3;
double height = Math.Max(y1, y2) - y3;
Rect rec = new Rect(x3, y3, width, height);
rec.Draw(ShapeCanvas);
rectangles.Add(rec);
// remove the temp geometry
ShapeCanvas.Children.Remove(tempRect);
}
}
isFirstClick = !isFirstClick;
}
private void ShapeCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (isFirstClick)
{
return;
}
x3 = e.GetPosition(this).X;
y3 = e.GetPosition(this).Y;
if(shapeChoice == 0)
{
double radius = Math.Sqrt((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1));
tempCircle.Width = radius * 2;
tempCircle.Height = radius * 2;
tempCircle.Stroke = Brushes.Red;
//ShapeCanvas.Children.Add(ellipse);
Canvas.SetLeft(tempCircle, x1 - radius);
Canvas.SetTop(tempCircle, y1 - radius);
}
else if(shapeChoice == 1)
{
double x2 = Math.Min(x1, x3);
double y2 = Math.Min(y1, y3);
double width = Math.Max(x1, x3) - x2;
double height = Math.Max(y1, y3) - y2;
tempRect.Width = width;
tempRect.Height = width;
tempRect.Stroke = Brushes.Blue;
Canvas.SetLeft(tempRect, x2);
Canvas.SetTop(tempRect, y2);
}
else if (shapeChoice == 2)
{
double x2 = Math.Min(x1, x3);
double y2 = Math.Min(y1, y3);
double width = Math.Max(x1, x3) - x2;
double height = Math.Max(y1, y3) - y2;
tempRect.Width = width;
tempRect.Height = height;
tempRect.Stroke = Brushes.Green;
Canvas.SetLeft(tempRect, x2);
Canvas.SetTop(tempRect, y2);
}
}
}
}
Circle.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace ShapeAnimator
{
internal class Circle
{
public Ellipse Ell = new Ellipse();
public double X;
public double Y;
public double Radius;
public int DeltaX = 1;
public int DeltaY = 1;
public Circle(double x, double y, double r)
{
X = x; Y = y; Radius = r;
}
public void Draw(Canvas canvas)
{
Ell.Width = 2 * Radius;
Ell.Height = 2 * Radius;
Ell.Stroke = Brushes.Red;
Canvas.SetLeft(Ell, X - Radius);
Canvas.SetTop(Ell, Y - Radius);
canvas.Children.Add(Ell);
}
public void Shift(Canvas canvas)
{
// Flip direction if hitting left & right walls
if (X + Radius > canvas.ActualWidth
|| X - Radius < 0)
{
DeltaX = -DeltaX;
}
// Flip direction if hitting left & right walls
if (Y + Radius > canvas.ActualHeight
|| Y - Radius < 0)
{
DeltaY = -DeltaY;
}
X = X + DeltaX;
Y = Y + DeltaY;
Canvas.SetLeft(Ell, X - Radius);
Canvas.SetTop(Ell, Y - Radius);
}
}
}
Rect.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace ShapeAnimator
{
internal class Rect
{
public Rectangle Rec = new Rectangle();
public double X;
public double Y;
public double Width;
public double Height;
public int DeltaX = 1;
public int DeltaY = 1;
public Rect(double x, double y, double width, double height)
{
X = x; Y = y; Width = width; Height = height;
}
public void Draw(Canvas canvas)
{
Rec.Width = Width;
Rec.Height = Height;
if (Rec.Width == Rec.Height)
Rec.Stroke = Brushes.Blue;
else
Rec.Stroke = Brushes.Green;
Canvas.SetLeft(Rec, X);
Canvas.SetTop(Rec, Y);
canvas.Children.Add(Rec);
}
public void Shift(Canvas canvas)
{
// Flip direction if hitting left & right walls
if (X + Width > canvas.ActualWidth
|| X < 0)
{
DeltaX = -DeltaX;
}
// Flip direction if hitting left & right walls
if (Y + Height > canvas.ActualHeight
|| Y < 0)
{
DeltaY = -DeltaY;
}
X = X + DeltaX;
Y = Y + DeltaY;
Canvas.SetLeft(Rec, X);
Canvas.SetTop(Rec, Y);
}
}
}
MainWindow.xaml
<Window x:Class="ShapeAnimator.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:local="clr-namespace:ShapeAnimator"
mc:Ignorable="d"
Title="Shape Animator" Height="450" Width="800"
Background="Black">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Canvas Name="ShapeCanvas"
Grid.Column="0" Grid.Row="0"
Background="Black"
Height="380"
MouseUp="ShapeCanvas_MouseUp"
MouseMove="ShapeCanvas_MouseMove"
>
</Canvas>
<WrapPanel Grid.Column="0" Grid.Row="1"
VerticalAlignment="Bottom" HorizontalAlignment="Center"
Margin="10">
<Button Width="150" Height="30" Click="CircleButton_Click">Circle</Button>
<Button Width="150" Margin="15 0" Click="SquareButton_Click">Square</Button>
<Button Width="150" Click="RectButton_Click">Rectangle</Button>
<Button Width="150" Click="ShiftButton_Click" Margin="15 0" >Shift</Button>
</WrapPanel>
</Grid>
</Window>
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报