您的位置:首页 > 其它

silverlight 碰撞检测

2012-12-10 09:08 253 查看
在游戏开发中其中一个常用的功能就是判断两个元素是否有相交在一起,让我们的游戏元素有一个与现实世界更相似的环境。

以下是一个可以判断两个FrameworkElement是否有碰撞到的实现方法:

1:  private bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)


2:  {


3:      // first see if sprite rectangles collide


4:      Rect rect1 = UserControlBounds(control1);


5:      Rect rect2 = UserControlBounds(control2);


6: 


7:      rect1.Intersect(rect2);


8:      if (rect1 == Rect.Empty)


9:      {


10:          // no collision - GET OUT!


11:          return false;


12:      }


13:      else


14:      {


15:          bool bCollision = false;


16:          Point ptCheck = new Point();


17: 


18:          // NOTE that creating the writeablebitmap is a bit intense


19:          // so we will do this once and store results in Tag property


20:          // in a real game, you might abstract this into a Sprite class.


21:          if (controlElem1 is Image)


22:              controlElem1.Tag = GetWriteableBitmap(control1);


23: 


24:          if (controlElem2 is Image)


25:              controlElem2.Tag = GetWriteableBitmap(control2);


26: 


27:          // now we do a more accurate pixel hit test


28:          for (int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x++)


29:          {


30:              for (int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y++)


31:              {


32:                  ptCheck.X = x;


33:                  ptCheck.Y = y;


34: 


35: 


36:                  if (CheckCollisionPoint(ptCheck, control1, controlElem1))


37:                      if (CheckCollisionPoint(ptCheck, control2, controlElem2))


38:                      {


39:                          bCollision = true;


40:                          break;


41:                      }


42: 


43:              }


44:              if (bCollision) break;


45:          }


46:          return bCollision;


47:      }


48:  }


49: 


50:  public bool CheckCollisionPoint(Point pt, FrameworkElement control, FrameworkElement controlElem)


51:  {


52:      if (controlElem is Image)


53:      {


54:          // NOTE that we saved the WB in the Tag object for performance.


55:          // in a real app, you might abstract this in your sprite class.


56:          WriteableBitmap wb = controlElem.Tag as WriteableBitmap;


57: 


58:          int width = wb.PixelWidth;


59:          int height = wb.PixelHeight;


60: 


61:          double offSetX = Convert.ToDouble(control.GetValue(Canvas.LeftProperty));


62:          double offSetY = Convert.ToDouble(control.GetValue(Canvas.TopProperty));


63: 


64:          pt.X = pt.X - offSetX;


65:          pt.Y = pt.Y - offSetY;


66: 


67:          int offset = Convert.ToInt32((width * pt.Y) + pt.X);


68: 


69:          return (wb.Pixels[offset] != 0);


70:      }


71:      else


72:      {


73:          List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, controlElem) as List<UIElement>;


74:          return (hits.Contains(controlElem));


75:      }


76:  }


77: 


78:  private WriteableBitmap GetWriteableBitmap(FrameworkElement control)


79:  {


80:      WriteableBitmap wb = new WriteableBitmap((int)control.Width, (int)control.Height); ;


81:      wb.Render(control, new TranslateTransform());


82:      wb.Invalidate();


83: 


84:      return wb;


85:  }


86: 


87:  public Rect UserControlBounds(FrameworkElement control)


88:  {


89:      Point ptTopLeft = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)), Convert.ToDouble(control.GetValue(Canvas.TopProperty)));


90:      Point ptBottomRight = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)) + control.Width, Convert.ToDouble(control.GetValue(Canvas.TopProperty)) + control.Height);


91: 


92:      return new Rect(ptTopLeft, ptBottomRight);


93:  }


94: 


检测:

1:  if (CheckCollision(sp1, sp1.ShipShell, sp2, sp2.ShipShell))


2:  {


3:      tb.Text = "true";


4:  }


5:  else


6:  {


7:      tb.Text = "false";


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