Collision detection during user control movement f

2019-08-03 03:32发布

If I am making two UserControls move in C# (WPF application in Visual Studio), I want to be able to detect collision between the two of them.

I currently am using the "doesIntersect" method, with an if statement to show a message box that says "Collision!."

It works fine, however, the message box doesn't show until the code is done executing, which makes sense for how I have it coded. Is there any way to get the message box to show as soon as they collide and not after they have already passed each other? Would I have to implement asynchronous programming here?

I currently am using a method for movement of the one object:

    public static void MoveTo(UserControl FoodX, double X, double Y)
    {
        Vector offset = VisualTreeHelper.GetOffset(FoodX);
        var top = offset.Y;
        TranslateTransform trans = new TranslateTransform();
        FoodX.RenderTransform = trans;
        DoubleAnimation anim1 = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(2));
        trans.BeginAnimation(TranslateTransform.YProperty, anim1);
    }

Then I have my collision code, where I put an invisible rect behind the image so I can use the Rect method:

    public static Rect rectbox;
    public bool Collision()
    {
        rectbox = new Rect(Canvas.GetLeft(rect1), Canvas.GetTop(rect1), rect1.Width, rect1.Height);
        bool doesIntersect = rect1.RenderedGeometry.Bounds.IntersectsWith(FoodImage.rectfood);
        return doesIntersect;
    }

1条回答
对你真心纯属浪费
2楼-- · 2019-08-03 03:39

I'm far from being an expert on WPF animations, but since nobody replied so far...

TranslateTransform has a Changed event that fires while the animation is moving the UI element. You can subscribe to this event with an event handler method, check for collision in your event handler, and if you detect collision, you can execute what you want.

The following code worked for me, i.e. the message box was shown instantly when the moving element collided with another element (I tested it with a Canvas containing a moving UserControl and another, static element):

public void MoveTo(UserControl FoodX, double X, double Y)
{
    Vector offset = VisualTreeHelper.GetOffset(FoodX);
    var top = offset.Y;
    TranslateTransform trans = new TranslateTransform();
    FoodX.RenderTransform = trans;
    DoubleAnimation anim1 = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(2));
    trans.BeginAnimation(TranslateTransform.YProperty, anim1);

    //Added line
    trans.Changed += RecalculateCollision;
}

public void RecalculateCollision(object sender, EventArgs e)
{            
    Rect r1 = BoundsRelativeTo(MovingBox, Canvas);
    Rect r2 = BoundsRelativeTo(StaticBox, Canvas);

    if (r1.IntersectsWith(r2))
    {
        MessageBox.Show("Collided");
    }
}

public static Rect BoundsRelativeTo(FrameworkElement element, Visual relativeTo)
{
    return element.TransformToVisual(relativeTo).TransformBounds(new Rect(element.RenderSize));
}
查看更多
登录 后发表回答