简体   繁体   English

WinRT / Metro中的碰撞检测

[英]Collision Detection in WinRT/Metro

I'm porting a Silverlight 4 application to WinRT, and the following collision detection code I was using looks like this (and works just fine in Silverlight 4): 我正在将Silverlight 4应用程序移植到WinRT,而我正在使用的以下冲突检测代码如下所示(并且在Silverlight 4中可以正常工作):

private bool IsCollision(Point p)
{
    var hostPoint = this.canvas.TransformToVisual(this.rootVisual).TransformPoint(p);
    return CheckCollisionPoint(hostPoint, this.canvas);
}

private bool CheckCollisionPoint(Point point, UIElement subTree)
{
    var hits = VisualTreeHelper.FindElementsInHostCoordinates(point, subTree);
    return hits.Count() > 0;
}

However, in my Metro app, it doesn't detect collisions correctly at all. 但是,在我的Metro应用中,它根本无法正确检测到碰撞。 I think it might be related to using the wrong rootVisual. 我认为这可能与使用错误的rootVisual有关。 The old code that worked out the rootVisual was like this: 得出rootVisual的旧代码是这样的:

private void FindRootVisual()
{
    this.rootVisual = this.canvas;
    while (this.rootVisual.Parent != null)
    {
        this.rootVisual = (FrameworkElement)this.rootVisual.Parent;
    }
}

But in WinRT, this.canvas has a Parent of null. 但是在WinRT中,this.canvas的父级为null。 I've tried setting the rootVisual directly to the MainPage object of my application, and to the Grid that the Canvas is in but it doesn't help. 我尝试将rootVisual直接设置为我的应用程序的MainPage对象,以及Canvas所在的Grid,但这无济于事。

Should this technique still work in WinRT/Metro, and if so, what rootVisual do I need to use? 这种技术是否仍应在WinRT / Metro中工作,如果可以,我需要使用什么rootVisual? If not, what would be a better way to do collision detection in WinRT? 如果没有,在WinRT中进行冲突检测的更好方法是什么?

I've found out what is going wrong. 我发现出了什么问题。 First, I do need to pass in my MainPage to be the rootVisual for it to transform the point correctly before the hit-test. 首先,我确实需要传入MainPage作为rootVisual以便它在命中测试之前正确转换点。

Second, FindElementsInHostCoordinates seems to return the subTree element itself as a hit, so this needs to be filtered out. 其次, FindElementsInHostCoordinates似乎返回subTree元素本身为subTree ,因此需要将其过滤掉。 In fact it is probably best to explicitly check that the hits found are the things you are collision testing against as I had another unwanted hit in the list as well. 实际上,最好最好是显式检查找到的命中是否是您要进行碰撞测试的对象,因为列表中还有另一个我不想要的命中。 Alternatively, you can set IsHitTestVisible to false on items you don't want to match (although doing this on the canvas itself results in no matches with any of its contents) 另外,您也可以在不想匹配的项目上将IsHitTestVisible设置为false(尽管在画布上执行此操作不会导致其任何内容与之匹配)

private bool CheckCollisionPoint(Point point, UIElement subTree)
{
    var hits = VisualTreeHelper.FindElementsInHostCoordinates(point, subTree);
    return hits.Any(x => x != subTree);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM