我在画布中有一个炸弹(元素),用双色移动(仅垂直),我想看看它是否击中飞机(也是画布上的元素)。 我写了这段代码:
private bool HitCheck()
{
AirPlaneRect.Location = airplane.PointToScreen(new Point(Canvas.GetLeft(airplane), Canvas.GetTop(airplane)));
Rect BombPos = new Rect(bombPoint.X, Canvas.GetTop(this),this.bombImage.Height, this.bombImage.Width);
if (BombPos.IntersectsWith(AirPlaneRect))
{
return true;
}
return false;
}
但由于某种原因,炸弹的位置始终是起始位置。 我正在使用一个每隔半秒调用一次这个方法的计时器。
答案 0 :(得分:0)
不是使用Timer
检查它们是否相交的周期性,而是在更改DoubleAnimation
时更准确地检查它。发生这种情况时,会引发CurrentTimeInvalidated
。
我创建了一个小样本来证明我的意思。这是XAML:
<Canvas>
<!--be shure to assign Top and Left of all objects-->
<Rectangle Canvas.Left="0" Canvas.Top="0" Name="bomb"
Width="20" Height="100" Fill="gray"/>
<Rectangle Canvas.Left="0" Canvas.Top="200" Name="airPlane"
Width="300" Height="50" Fill="lightblue"/>
<Canvas.Triggers>
<!--Run the animation at startup-->
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard >
<Storyboard >
<DoubleAnimation Name="doubleAnimation"
Storyboard.TargetName="bomb"
Storyboard.TargetProperty="(Canvas.Top)"
From="0" To="400" Duration="0:0:5"
CurrentTimeInvalidated="CurrentTimeInvalidated"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
背后的代码:
private void CurrentTimeInvalidated(object sender, EventArgs e)
{
if (HitTest(airPlane, bomb))
{
MessageBox.Show("Hit!");
//unregister the event handler to avoid to see the messagebox more than once
doubleAnimation.CurrentTimeInvalidated -= CurrentTimeInvalidated;
}
}
static bool HitTest(FrameworkElement airPlane, FrameworkElement bomb)
{
var r1 = new Rect(Canvas.GetLeft(airPlane), Canvas.GetTop(airPlane), airPlane.ActualWidth, airPlane.ActualHeight);
var r2 = new Rect(Canvas.GetLeft(bomb), Canvas.GetTop(bomb), bomb.ActualWidth, bomb.ActualHeight);
return r1.IntersectsWith(r2);
}
如果你这样做,它应该有效。或者你的代码结构与我的代码结构有何不同?