freeflow488
freeflow488

Reputation: 39

Collision detection during user control movement for WPF C# in Visual Studio

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;
    }

Upvotes: 1

Views: 1761

Answers (1)

Leaky
Leaky

Reputation: 3636

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));
}

Upvotes: 2

Related Questions