MonoMatrix
MonoMatrix

Reputation: 123

Collision detection Xamarin.Forms

I'm trying to detect a collision between two Xamarin. Forms Controls (BoxViews), but I can't find a way to do it. I have a button that what it does is to decrease the TranslationY of a BoxView until it collides with the other BoxView. I remember that with WinForms this could be done with IntersectsWith, but apparently here does not work, I currently have this:

public class Main : ContentPage
{
    public BoxView pjOne = new BoxView { BackgroundColor = Color.Red, HeightRequest = 100, WidthRequest = 100, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.StartAndExpand };
    public BoxView pjTwo = new BoxView { BackgroundColor = Color.Green, HeightRequest = 100, WidthRequest = 100, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand };
    public Button btnDown = new Button { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.End, Text = "Down", TextColor = Color.White };

    public Main()
    {
        btnDown.Clicked += (s, e) =>
        {
            if(!pjOne.Bounds.IntersectsWith(pjTwo.Bounds))
            {
                pjOne.TranslationY -= 100; //If it does not detect collision it decreases the TranslationY
            }
            else
            {
                pjOne.TranslationY += 100; //If it detects collision it increases the TranslationY
            }
        };

        Content = new StackLayout
        {
            Children =
            {
                pjOne,
                pjTwo,
                btnDown
            }
        };
    }
}

But this doesn't work, it never detects the collision between the two BoxView.

Upvotes: 0

Views: 459

Answers (1)

James
James

Reputation: 381

Bounds do not get updated when a Translation is applied.

From the docs:

Bounds is assigned during the Layout cycle by a call to Layout(Rectangle).

I would try

  1. calling Layout with the new location you want to translate the BoxView to
  2. create a rectangle for pjOne and pjTwo. Then you could use the Xamarin.Forms.Rectangle.IntercectsWith method.

Here is an untested example of how to do this:

var pjRectOne = new Rectangle(pjOne.X + pjOne.TranslationX, pjOne.Y + pjOne.TranslationY, pjOne.Width, pjOne.Height);
var pjRectTwo = new Rectangle(pjTwo.X + pjTwo.TranslationX, pjTwo.Y + pjTwo.TranslationY, pjTwo.Width, pjTwo.Height);
if (pjRectOne.IntercectsWith(pjRectTwo))
{

}

Note: if pjOne or pjTwo are children of a view, their X and Y positions will be relative to the parent. To get the absolute X and Y, loop through all their parents by doing something like this

var y = pjOne.Y; 
var parent = pjOne.ParentView; 
while (parent != null) 
{ 
    y += parent.Y; 
    parent = parent.ParentView; 
} 

Hope this helped you out :)

Upvotes: 1

Related Questions