AABB 检测边缘碰撞 [libGDX]
AABB detecting edge collision [libGDX]
我在整个网络上搜索了回复,但一无所获。
无论如何,我想做的是实现正方形碰撞,但我想知道正方形在哪些边上与另一个正方形发生碰撞。例如,我想检查玩家是否与正方形的上边缘或正方形的左边缘发生碰撞。
这有点痛苦,因为它是 java 但这是解决方案。如果两个矩形相交,我们只关心生成的矩形的大小。每次我们比较它的宽度和高度以获得碰撞的最佳边缘。
public static class AABB {
float minX, minY, maxX, maxY;
public AABB(int a, int b, int c, int d) {
minX = a;
minY = b;
maxX = c;
maxY = d;
}
float cx, cy;
public void updateCenter() {
cx = minX + (maxX - minX)/2;
cy = minY + (maxY - minY)/2;
}
public Side detect(AABB o) {
if(maxX < o.minX || minX > o.maxX || maxY < o.minY || minY > o.maxY) return Side.None;
o.updateCenter();
updateCenter();
boolean
top = minY < o.cy,
bottom = maxY > o.cy,
left = maxX > o.cx,
right = minX < o.cx;
// depends on how you define y axis, in this case it increases upwards
if(top && left) {
return o.minY - maxY > minX - o.maxX ? Side.Top : Side.Left;
}
if(top && right) {
return o.minY - maxY > o.minX - maxX ? Side.Top : Side.Right;
}
if(bottom && right) {
return minY - o.maxY > o.minX - maxX ? Side.Bottom : Side.Right;
}
if(bottom && left) {
return minY - o.maxY > minX - o.maxX ? Side.Bottom : Side.Right;
}
throw new RuntimeException("should not reach");
}
enum Side {
Left, Right, Top, Bottom, None
}
}
public static void main(String[] args){
AABB base = new AABB(0, 0, 10, 10);
System.out.println(base.detect(new AABB(12, 0, 20, 10)) == Side.None);
System.out.println(base.detect(new AABB(10, 0, 20, 10)) == Side.Right);
System.out.println(base.detect(new AABB(-10, 0, 0, 10)) == Side.Left);
System.out.println(base.detect(new AABB(0, 10, 10, 20)) == Side.Top);
System.out.println(base.detect(new AABB(0, -10, 10, 0)) == Side.Bottom);
System.out.println(base.detect(new AABB(10, 7, 20, 17)) == Side.Right);
System.out.println(base.detect(new AABB(-10, 7, 0, 17)) == Side.Left);
System.out.println(base.detect(new AABB(7, 10, 17, 20)) == Side.Top);
System.out.println(base.detect(new AABB(7, -10, 17, 0)) == Side.Bottom);
}
我在整个网络上搜索了回复,但一无所获。 无论如何,我想做的是实现正方形碰撞,但我想知道正方形在哪些边上与另一个正方形发生碰撞。例如,我想检查玩家是否与正方形的上边缘或正方形的左边缘发生碰撞。
这有点痛苦,因为它是 java 但这是解决方案。如果两个矩形相交,我们只关心生成的矩形的大小。每次我们比较它的宽度和高度以获得碰撞的最佳边缘。
public static class AABB {
float minX, minY, maxX, maxY;
public AABB(int a, int b, int c, int d) {
minX = a;
minY = b;
maxX = c;
maxY = d;
}
float cx, cy;
public void updateCenter() {
cx = minX + (maxX - minX)/2;
cy = minY + (maxY - minY)/2;
}
public Side detect(AABB o) {
if(maxX < o.minX || minX > o.maxX || maxY < o.minY || minY > o.maxY) return Side.None;
o.updateCenter();
updateCenter();
boolean
top = minY < o.cy,
bottom = maxY > o.cy,
left = maxX > o.cx,
right = minX < o.cx;
// depends on how you define y axis, in this case it increases upwards
if(top && left) {
return o.minY - maxY > minX - o.maxX ? Side.Top : Side.Left;
}
if(top && right) {
return o.minY - maxY > o.minX - maxX ? Side.Top : Side.Right;
}
if(bottom && right) {
return minY - o.maxY > o.minX - maxX ? Side.Bottom : Side.Right;
}
if(bottom && left) {
return minY - o.maxY > minX - o.maxX ? Side.Bottom : Side.Right;
}
throw new RuntimeException("should not reach");
}
enum Side {
Left, Right, Top, Bottom, None
}
}
public static void main(String[] args){
AABB base = new AABB(0, 0, 10, 10);
System.out.println(base.detect(new AABB(12, 0, 20, 10)) == Side.None);
System.out.println(base.detect(new AABB(10, 0, 20, 10)) == Side.Right);
System.out.println(base.detect(new AABB(-10, 0, 0, 10)) == Side.Left);
System.out.println(base.detect(new AABB(0, 10, 10, 20)) == Side.Top);
System.out.println(base.detect(new AABB(0, -10, 10, 0)) == Side.Bottom);
System.out.println(base.detect(new AABB(10, 7, 20, 17)) == Side.Right);
System.out.println(base.detect(new AABB(-10, 7, 0, 17)) == Side.Left);
System.out.println(base.detect(new AABB(7, 10, 17, 20)) == Side.Top);
System.out.println(base.detect(new AABB(7, -10, 17, 0)) == Side.Bottom);
}