XNA-2D碰撞-使用像素偵測

XNA-2D碰撞-使用像素偵測

上一篇使用XNA-2D碰撞-使用矩形偵測的缺點就是對於不規則的物體沒輒!而遊戲裡常常都是不規則的物體,所以我們來試試看用像素偵測的方式,

如此不論圖形長什麼樣子都可以準確的偵測出來。

首先我們要將會碰撞的物體其背景變成透明的,png檔案有支援透明背景,我們就用png圖檔來試驗!

像素碰撞的想法如下

未碰撞:

 

未命名 -4

碰撞:

 

 未命名 -6

其實還是要有一個碰撞矩形,而當此矩形發生碰撞後,取得重疊的區域,再檢查此區域內兩張圖的每一個像素,若出現有一個點是兩張圖都不透明,則發生碰撞。

因為要取得圖形的顏色,我們在有一個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