制作双重输入矩阵

时间:2018-09-28 18:36:34

标签: java

我正在尝试实现一个类,以检查两个游戏对象是否相交。谁能给我一个更好的解决方案/更优雅的解决方案?

基本上,我想addCollision并知道一个对象collidesWith是否另一个。双重输入矩阵似乎是个好主意。

    private class CollisionMatrix {

    private boolean[][] matrix;
    private HashMap<Tag, Integer> matrixIndexes = new HashMap<Tag, Integer>();

    public CollisionMatrix() {
        int i = 0;
        for (Tag tag : Tag.values())
            matrixIndexes.put(tag, i++);
        matrix = new boolean[i][i];
    }

    private void addCollision(Tag tag1, Tag tag2) {
        int p1 = matrixIndexes.get(tag1);
        int p2 = matrixIndexes.get(tag2);
        matrix[p1][p2] = true;
        matrix[p2][p1] = true;
    }

    private boolean collidesWith(Tag tag1, Tag tag2) {
        int p1 = matrixIndexes.get(tag1);
        int p2 = matrixIndexes.get(tag2);
        return matrix[p1][p2] || matrix[p2][p1];
    }

}

1 个答案:

答案 0 :(得分:0)

这不是一个完整的答案,但它应该使您踏上一条获得更完整解决方案的道路。

最简单(效率不高)的方法是先列出可以相互碰撞的对象的列表,然后在每个时间帧中遍历列表中的每个对象,并检查对象是否碰撞(共享相同的空间或边界体积)与列表中的另一个空间。

伪代码:

L: list of objects that can potentially collide.
t: time

for each frame in t {
    for each object obj in L {
        P: list of objects without obj
        for each object otherObj in P {
             does obj collide with otherObj
        }
    }
}

虽然这在技术上是可行的,但它不是一个好的解决方案,因为一旦您开始拥有许多对象,它就会非常慢,并且不需要花很多时间就可以使其变慢。

要实时实现此目的,您需要添加一些加速技术。 这些加速技术之一是使用“边界体积层次”或BVH。 https://en.wikipedia.org/wiki/Bounding_volume_hierarchy

简而言之,BVH是一种技术或算法,可以快速查找哪些对象可能发生碰撞。

它通常使用某种类型的树结构来跟踪所述对象所占据的位置和体积。树形结构提供的查找时间比仅线性遍历一个列表要快得多。

树的每个级别都提供了包围体积的层次结构(对象可能占据的空间)。树的顶层为特定对象提供了更大的体积(更粗糙,更不颗粒或更不适合对象的形状),但是如果所涉及的对象不在同一空间中,则更容易丢弃(您几乎不会知道)计算得出该对象将永远不会与相同边界体积内的任何物体发生碰撞)。您进入的树越深,边界体积得到的对象形状越细化或更适合,直到获得碰撞的对象。

希望这会有所帮助:)