java 實現精確碰撞檢測。

cnmm22 原創。

http://blog.csdn.net/cnmm22/article/details/45220551

用我的方法,你可以在java 裏實現精確的斜角矩形,平行四邊形,不規則矩形,不規則多邊形與圓形的碰撞檢測。

我們知道,在java 裏有一個類,x.getRect().intersects(x1.getRect() 可以實現規則矩形的碰撞檢測:

僅使用 getRect().intersects(w.getRect()

僅使用 getRect().intersects(w.getRect()

僅使用 getRect().intersects(w.getRect()

這是無法容忍的“碰撞檢測”。這不是我要的遊戲效果。

在使我的方法後:

較爲精確碰撞檢測

較爲精確碰撞檢測

較爲精確碰撞檢測

cnmm22 原創,轉載請隨意。

實現方法:我們必須把所有的碰撞分爲兩類:與圓形和與多邊形。

圓形與圓形解決方案:檢測兩個碰撞對象的圓心距離,跟兩者半徑之和做比較。

我把要使用的方法都封裝好了,以便您直接使用 :

    /**  步驟一、檢測兩個圓心距離 */
    public static double getDistance(Point p, double ox, double oy) {
        double _x = Math.abs(ox - p.x);
        double _y = Math.abs(oy - p.y);
        return Math.sqrt(_x * _x + _y * _y);
    }

每一張圓形的透明 png圓形圖片,我們都有一個尺寸大小,我們按尺寸大小,得到其半徑。

而要碰撞的兩個圓心座標我們是很好得到的,這個相信我不須解釋。

/* 步驟二、檢測兩個圓心距離,與兩者半徑之和做比較,範例代碼: /
.

            Point p1 = new Point(x + W / 2, y + H / 2);
            if (Unit.getDistance(p1, w.yx, w.yy) < w.yr) {

.

以上就完成了圓形的碰撞檢測。

多邊形:騷複雜點,。

解決方案:1、描邊,2,檢測邊到點距離。

例如這個圖形:
cnmm22原創

先描出4個定點,這樣,能以這4個點組合成4條線段。在分別檢測每一條線段與對象中心的距離即可。

示例代碼:
……………………….

img = tk.getImage(Wall.class.getClassLoader().getResource("images/4/k8.png"));
            rx1 = 1;
            rx2 = 14784;
            w = 168;
            h = 88;

            rx3 = 2;

            x3 = x;
            y3 = y + 5;

            w3 = w - 15;
            h3 = h - 5;

            px11 = x + 14;
            px12 = y + 35;

            px21 = x + 136;
            px22 = y + 7;

            px31 = x + 4;
            px32 = y + 85;

            px41 = x + 149;
            px42 = y + 53;

……………………….

px11,px12,是它的第一個點,px21,px22,是它的第二個點,以此類推。x,y是這張矢量圖最左上角滴點,不管那個點有沒有像素,或者是透明,它都是 x, y。這樣通過圖像工具,我們很容易得到一組 px1-pxn, px12-pxn2。

示例代碼:(分別檢測每一條線段與對象中心的距離)

if (Unit.pointToLine(w.px11, w.px12, w.px21, w.px22, x + W / 2, y + H / 2) < 24) {

                stay();

                return true;
            }
            if (Unit.pointToLine(w.px11, w.px12, w.px31, w.px32, x + W / 2, y + H / 2) < 24) {

                stay();

                return true;
            }
            if (Unit.pointToLine(w.px31, w.px32, w.px41, w.px42, x + W / 2, y + H / 2) < 24) {

                stay();

                return true;
            }
            if (Unit.pointToLine(w.px21, w.px22, w.px41, w.px42, x + W / 2, y + H / 2) < 24) {

                stay();

                return true;

其中 x + W / 2, y + H / 2 ,是點座標,24是檢測距離。以上只是範例。

    /**  封裝方法:檢測邊到點距離 */
    static double pointToLine(int x1, int y1, int x2, int y2, int x0, int y0) {
        double space = 0;
        double a, b, c;
        a = lineSpace(x1, y1, x2, y2);// 線段的長度
        b = lineSpace(x1, y1, x0, y0);// (x1,y1)到點的距離
        c = lineSpace(x2, y2, x0, y0);// (x2,y2)到點的距離
        if (c <= 0.000001 || b <= 0.000001) {
            space = 0;
            return space;
        }
        if (a <= 0.000001) {
            space = b;
            return space;
        }
        if (c * c >= a * a + b * b) {
            space = b;
            return space;
        }
        if (b * b >= a * a + c * c) {
            space = c;
            return space;
        }
        double p = (a + b + c) / 2;// 半周長
        double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海倫公式求面積
        space = 2 * s / a;// 返回點到線的距離(利用三角形面積公式求高)
        return space;
    }

無論如何,解決多邊形碰撞檢測,描邊將會是一個相當大工作量的工作,但是一旦使用熟練後,其實也是相當簡便。因爲有圖形工具。

cnmm22 原創

cnmm22 原創

這樣就很迅速得到了 px11,px12,px21,px22 ;px31,px32,px41,px42 類似。

以上就完成了不規則矩形的碰撞檢測。

那多邊形怎樣檢測?

多邊形方法類似,多描幾條邊出來,再分辨判斷點到線距離即可。我就不在贅述了。

假設要檢測的對象是一個橢圓又怎嗎辦?

你可以參考這樣的方法:
這裏寫圖片描述

記住,你描的邊越多,精確度越高,工作量越大。

使用我的方法,你可以最大限度提高碰撞檢測的精確程度,並且可以避免像素級碰撞檢測帶來的巨大性能損耗,若碰撞的對象爲多邊形與多邊形碰撞,或多邊形與曲線碰撞,無法使用我的方法檢測,而實際中,這種碰撞很少,這種情況下,可以建立像素矩陣,一般的做法比如一個200*200像素的圖片,我們則需要做一個[200]*[200]的數組,進行約40000次的遍歷,來完成1幀裏滴碰撞檢測,還要考慮到透明度的計算,其性能消耗相當可觀。

發佈了53 篇原創文章 · 獲贊 15 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章