我正在尝试实现一个类,以检查两个游戏对象是否相交。谁能给我一个更好的解决方案/更优雅的解决方案?
基本上,我想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];
}
}
答案 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是一种技术或算法,可以快速查找哪些对象可能发生碰撞。
它通常使用某种类型的树结构来跟踪所述对象所占据的位置和体积。树形结构提供的查找时间比仅线性遍历一个列表要快得多。
树的每个级别都提供了包围体积的层次结构(对象可能占据的空间)。树的顶层为特定对象提供了更大的体积(更粗糙,更不颗粒或更不适合对象的形状),但是如果所涉及的对象不在同一空间中,则更容易丢弃(您几乎不会知道)计算得出该对象将永远不会与相同边界体积内的任何物体发生碰撞)。您进入的树越深,边界体积得到的对象形状越细化或更适合,直到获得碰撞的对象。
希望这会有所帮助:)