XNA-2D碰撞-使用像素偵測
上一篇使用XNA-2D碰撞-使用矩形偵測的缺點就是對於不規則的物體沒輒!而遊戲裡常常都是不規則的物體,所以我們來試試看用像素偵測的方式,
如此不論圖形長什麼樣子都可以準確的偵測出來。
首先我們要將會碰撞的物體其背景變成透明的,png檔案有支援透明背景,我們就用png圖檔來試驗!
像素碰撞的想法如下
未碰撞:
碰撞:
其實還是要有一個碰撞矩形,而當此矩形發生碰撞後,取得重疊的區域,再檢查此區域內兩張圖的每一個像素,若出現有一個點是兩張圖都不透明,則發生碰撞。
因為要取得圖形的顏色,我們在有一個Color[]的陣列,並在初始化的時候將圖形的顏色資訊填入,片段程式碼如下:
protected Color[] pixelColors;
public IPixelCollideObject(Texture2D image)
: base(image) {
collideRectangle = new Rectangle((int)position.X, (int)position.Y, image.Width, image.Height);
pixelColors = new Color[image.Width * image.Height];
image.GetData<Color>(pixelColors);
}
Texture2D.GetData可以讓我們取得圖片的資訊。
接著就是主要的判段程式碼:
public bool CollideCheck(ICollideable obj) {
if (collodeable) {
PixelCollideObject o = obj as PixelCollideObject;
if (o != null) {
Rectangle intersect = Rectangle.Intersect(collideRectangle, o.collideRectangle);
if (!intersect.IsEmpty) {
for (int y = intersect.Top; y < intersect.Bottom; y++) {
for (int x = intersect.Left; x < intersect.Right; x++) {
Color colorA = pixelColors[(x - collideRectangle.Left) + (y - collideRectangle.Top) * collideRectangle.Width];
Color colorB = o.pixelColors[(x - o.collideRectangle.Left) + (y - o.collideRectangle.Top) * o.collideRectangle.Width];
if (colorA.A != 0 && colorB.A != 0) return true;
}
}
}
}
}
return false;
}
取得重疊區域使用Rectangle.Intersect函式,他是一個靜態的函式,傳入兩個矩形,將重疊部分回傳,若無重疊則回傳Rectangle.Empty。
迴圈則是由左而又由上而下檢查每個像素,若兩張圖在重疊區域有都不是透明的點的話,就表示發生碰撞了!
範例下載:WindowsGame1.rar