簡體   English   中英

Box2D中的碰撞檢測

[英]Collision Detection in Box2D

所以我在游戲中使用Box2D進行碰撞檢測。 我有一個圖塊地圖,其中包含有關地形的信息:目前,這只是一個具有道路或草地的char [] []。 現在,在每個級別的開始,我想創建一個矩形來描述不同的地形,但是我希望這些矩形得到優化,並且顯然需要相當多的算法。

我的第一種方法是在關卡開始時為地圖中的每個圖塊創建一個單獨的地形。 FPS降至5。

我的第二個想法是在玩家沿着地圖移動時,簡單地為地形創建不同的矩形,刪除看不見的矩形。 盡管仍然會有很多矩形,但是會少得多。

我還沒有嘗試過第二種方法,但是我想知道:對我來說,有沒有一種簡單的方法可以有效地對具有大圖塊貼圖的地形進行碰撞檢測?

謝謝。

嘗試結合瓷磚。 例如,如果您有16個圖塊的16個矩形碰撞體積,例如...

* * * *
* * * *
* * * *
* * * *

您顯然可以將這些圖塊組合成一個大矩形。

現在,如果您將瓷磚排列成奇怪的形狀,事情就會變得更加困難,也許像這樣……

**---
****-
*--**
-*-*-

我最近剛剛在游戲中使用四叉樹清掃和修剪功能解決了這個問題。 (嚴格修剪和修剪不是必需的,這是一種優化。)

四叉樹將方形圖塊划分為更大的矩形,然后遍歷四叉樹生成的矩形,如果寬度相同,則將其合並,然后再次遍歷它們,並以相似的高度合並。 重復直到無法再合並它們,然后生成碰撞體積。

這是我提出的有關最佳還原的問題的鏈接 聽起來很困難,我可能不會實現,而我目前的方法運行良好。

一些代碼:

do {
    lastCompressSize = currentOutput;
    this.runHorizontalCompression(this.output1, this.output2);
    this.output1.clear();
    this.runVerticalCompression(this.output2, this.output1);
    this.output2.clear();
    currentOutput = this.output1.size;
    iterations += 1;
}while (lastCompressSize > currentOutput);

public void runHorizontalCompression(Array<SimpleRect> input,
        Array<SimpleRect> output) {
    input.sort(this.xAxisSort);
    int x2 = -1;
    final SimpleRect newRect = this.rectCache.retreive();
    for (int i = 0; i < input.size; i++) {
        SimpleRect r1 = input.get(i);
        newRect.set(r1);
        x2 = newRect.x + newRect.width;
        for (int j = i + 1; j < input.size; j++) {
            SimpleRect r2 = input.get(j);
            if (x2 == r2.x && r2.y == newRect.y
                    && r2.height == newRect.height) {
                newRect.width += r2.width;
                x2 = newRect.x + newRect.width;
                input.removeIndex(j);
                j -= 1;
            } else if (x2 < r2.x)
                break;
        }
        SimpleRect temp = this.rectCache.retreive().set(newRect);
        output.add(temp);
    }
}

public void runVerticalCompression(Array<SimpleRect> input,
        Array<SimpleRect> output) {
    input.sort(this.yAxisSort);
    int y2 = -1;
    final SimpleRect newRect = this.rectCache.retreive();
    for (int i = 0; i < input.size; i++) {
        SimpleRect r1 = input.get(i);
        newRect.set(r1);
        y2 = newRect.y + newRect.height;
        for (int j = i + 1; j < input.size; j++) {
            SimpleRect r2 = input.get(j);
            if (y2 == r2.y && r2.x == newRect.x
                    && r2.width == newRect.width) {
                newRect.height += r2.height;
                y2 = newRect.y + newRect.height;
                input.removeIndex(j);
                j -= 1;
            } else if (y2 < r2.y)
                break;
        }
        SimpleRect temp = this.rectCache.retreive().set(newRect);
        output.add(temp);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM