您的位置:首页 > 其它

不规则图形的碰撞检测

2010-02-07 16:32 302 查看
public static class CheckHit
{
public static bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)
{
// first see if sprite rectangles collide
Rect rect1 = UserControlBounds(control1);
Rect rect2 = UserControlBounds(control2);
rect1.Intersect(rect2);
if (rect1 == Rect.Empty)
{
// no collision - GET OUT!
return false;
}
else
{
bool bCollision = false;
Point ptCheck = new Point();
// NOTE that creating the writeablebitmap is a bit intense
// so we will do this once and store results in Tag property
// in a real game, you might abstract this into a Sprite class.

if (controlElem1 is Image)
controlElem1.Tag = GetWriteableBitmap(control1);
if (controlElem2 is Image)
controlElem2.Tag = GetWriteableBitmap(control2);

// now we do a more accurate pixel hit test

for (int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x++)
{
for (int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y++)
{
ptCheck.X = x;
ptCheck.Y = y;

if (CheckCollisionPoint(ptCheck, control1, controlElem1))
if (CheckCollisionPoint(ptCheck, control2, controlElem2))
{
bCollision = true;
break;
}
}
if (bCollision) break;
}
return bCollision;
}
}

private static bool CheckCollisionPoint(Point pt, FrameworkElement control, FrameworkElement controlElem)
{
if (controlElem is Image)
{
// NOTE that we saved the WB in the Tag object for performance.
// in a real app, you would abstract this in your sprite class.
WriteableBitmap wb = controlElem.Tag as WriteableBitmap;
int width = wb.PixelWidth;
double offSetX = Convert.ToDouble(control.GetValue(Canvas.LeftProperty));
double offSetY = Convert.ToDouble(control.GetValue(Canvas.TopProperty));
pt.X = pt.X - offSetX;
pt.Y = pt.Y - offSetY;
int offset = Convert.ToInt32((width * pt.Y) + pt.X);
return (wb.Pixels[offset] != 0);
}
else
{

List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, controlElem) as List<UIElement>;
return (hits.Contains(controlElem));
}

}

private static WriteableBitmap GetWriteableBitmap(FrameworkElement control)
{
WriteableBitmap wb = new WriteableBitmap((int)control.Width, (int)control.Height);
wb.Render(control, new TranslateTransform());
wb.Invalidate();

return wb;
}

private static Rect UserControlBounds(FrameworkElement control)
{
Point ptTopLeft = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)), Convert.ToDouble(control.GetValue(Canvas.TopProperty)));
Point ptBottomRight = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)) + control.Width, Convert.ToDouble(control.GetValue(Canvas.TopProperty)) + control.Height);

return new Rect(ptTopLeft, ptBottomRight);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: