碰撞检测问题
Collision Detection Issues
我的游戏碰撞检测系统有点问题。
游戏中有几个相互连接的结构。然而,当它们之间有另一个结构时,它们不应该连接。
由于某些奇怪的原因,当在它们后面的一条直线上有一个结构时,它有时无法连接到直接相邻的结构。它很少产生其他奇怪的连接。
图片:
红色标记的节点应该是连接的。
代码:
public void drawConnections(Graphics g) {
ArrayList<EnergyContainer> structurecopy = (ArrayList<EnergyContainer>) Mainclass.structures.clone(); //all structures in a list
structurecopy.remove(this); //as we are member of the list
structurecopy.removeIf(t -> (!hasStructureInRangeWithoutObstaclesInBetween(t)));
structurecopy.removeIf(t -> !t.receivesEnergyfromNeighbors()); //unimportant check if it is allowed to connect (its working)
structurecopy.forEach(t -> drawConnectionTo(t, g)); //also works fine
}
public boolean hasStructureInRangeWithoutObstaclesInBetween(Structure structureWhichShouldBeInRange) {
// if in Range
if (getRange() >= Math.hypot(structureWhichShouldBeInRange.getX() - getX(),
structureWhichShouldBeInRange.getY() - getY())){ //checks if structure is in range
ArrayList<EnergyContainer> structureclone = (ArrayList<EnergyContainer>) Mainclass.structures.clone();
structureclone.remove(this); //again removes itself from the list
structureclone.remove(structureWhichShouldBeInRange); //also removes target - so it doesn't block itself
structureclone.removeIf(t -> !t.collidesWithLine(this.getX(), structureWhichShouldBeInRange.getX(),
this.getY(), structureWhichShouldBeInRange.getY())); //removes it when it does not collide
return structureclone.size() == 0; //returns true when no collisions are found
}
return false;
}
public boolean collidesWithLine(int x1, int x2, int y1, int y2) {
// Line Segment - Circle Collision Detection
double dx = x2 - x1;
double dy = y2 - y1;
double a = dx * dx + dy * dy; //this is the distance
double b = 2 * dx * (x1 - getX()) + 2 * dy * (y1 - getY());
double c = getX() * getX() + getY() * getY() + x1 * x1 + y1 * y1 - 2 * (getX() * x1 + getY() * y1)
- getCollisionRadius() * getCollisionRadius();
double discriminant = b * b - 4 * a * c;
return discriminant >= 0; // no intersection -> discriminant <0
}
(我只为这段文字添加了注释,如果它们会导致编译错误,请忽略它们)。
谁能告诉我我做错了什么?
假设:
1 如果我没理解错的话,这些是一些结构的方法class。
2 hasStructureInRangeWithoutObstaclesInBetween 是 collidesWithLine 的唯一调用者,或者至少这就是问题的呈现方式。
因为 (2) b 总是 0。
我有一种感觉,这不是你的本意。请重新访问您的 collidesWithLine 方法。
这里可能有几个问题:
首先: 正如 Marat 所说:b
可能是 return 值 0。如果您的 getX()
和 getY()
是 returning x1
和 y1
。如果是这样的话,你实际上是在这样做:(2dx * 0) + (2dy * 0)
。如果是这样的话,它会对你以后的方程式产生负面影响。
其次:您很可能总是returning true
来自您的礼貌最终等式:
double discriminant = b * b - 4 * a * c;
//This breaks down to discriminant = b^2 * 4ac
即使此时b
为0,只要a
或c
的值大于0,return discriminant >= 0;
就会为真;
我会高度建议在我提到的两个部分放置一个断点,并在代码执行前后检查你的值,这样你就可以看到数学是怎么回事.
此外,Unity API 具有碰撞检测功能。你应该看看那个。 https://docs.unity3d.com/Manual/PhysicsSection.html
希望对您有所帮助。
我的游戏碰撞检测系统有点问题。 游戏中有几个相互连接的结构。然而,当它们之间有另一个结构时,它们不应该连接。
由于某些奇怪的原因,当在它们后面的一条直线上有一个结构时,它有时无法连接到直接相邻的结构。它很少产生其他奇怪的连接。
图片:
红色标记的节点应该是连接的。
代码:
public void drawConnections(Graphics g) {
ArrayList<EnergyContainer> structurecopy = (ArrayList<EnergyContainer>) Mainclass.structures.clone(); //all structures in a list
structurecopy.remove(this); //as we are member of the list
structurecopy.removeIf(t -> (!hasStructureInRangeWithoutObstaclesInBetween(t)));
structurecopy.removeIf(t -> !t.receivesEnergyfromNeighbors()); //unimportant check if it is allowed to connect (its working)
structurecopy.forEach(t -> drawConnectionTo(t, g)); //also works fine
}
public boolean hasStructureInRangeWithoutObstaclesInBetween(Structure structureWhichShouldBeInRange) {
// if in Range
if (getRange() >= Math.hypot(structureWhichShouldBeInRange.getX() - getX(),
structureWhichShouldBeInRange.getY() - getY())){ //checks if structure is in range
ArrayList<EnergyContainer> structureclone = (ArrayList<EnergyContainer>) Mainclass.structures.clone();
structureclone.remove(this); //again removes itself from the list
structureclone.remove(structureWhichShouldBeInRange); //also removes target - so it doesn't block itself
structureclone.removeIf(t -> !t.collidesWithLine(this.getX(), structureWhichShouldBeInRange.getX(),
this.getY(), structureWhichShouldBeInRange.getY())); //removes it when it does not collide
return structureclone.size() == 0; //returns true when no collisions are found
}
return false;
}
public boolean collidesWithLine(int x1, int x2, int y1, int y2) {
// Line Segment - Circle Collision Detection
double dx = x2 - x1;
double dy = y2 - y1;
double a = dx * dx + dy * dy; //this is the distance
double b = 2 * dx * (x1 - getX()) + 2 * dy * (y1 - getY());
double c = getX() * getX() + getY() * getY() + x1 * x1 + y1 * y1 - 2 * (getX() * x1 + getY() * y1)
- getCollisionRadius() * getCollisionRadius();
double discriminant = b * b - 4 * a * c;
return discriminant >= 0; // no intersection -> discriminant <0
}
(我只为这段文字添加了注释,如果它们会导致编译错误,请忽略它们)。
谁能告诉我我做错了什么?
假设: 1 如果我没理解错的话,这些是一些结构的方法class。 2 hasStructureInRangeWithoutObstaclesInBetween 是 collidesWithLine 的唯一调用者,或者至少这就是问题的呈现方式。
因为 (2) b 总是 0。 我有一种感觉,这不是你的本意。请重新访问您的 collidesWithLine 方法。
这里可能有几个问题:
首先: 正如 Marat 所说:b
可能是 return 值 0。如果您的 getX()
和 getY()
是 returning x1
和 y1
。如果是这样的话,你实际上是在这样做:(2dx * 0) + (2dy * 0)
。如果是这样的话,它会对你以后的方程式产生负面影响。
其次:您很可能总是returning true
来自您的礼貌最终等式:
double discriminant = b * b - 4 * a * c;
//This breaks down to discriminant = b^2 * 4ac
即使此时b
为0,只要a
或c
的值大于0,return discriminant >= 0;
就会为真;
我会高度建议在我提到的两个部分放置一个断点,并在代码执行前后检查你的值,这样你就可以看到数学是怎么回事.
此外,Unity API 具有碰撞检测功能。你应该看看那个。 https://docs.unity3d.com/Manual/PhysicsSection.html
希望对您有所帮助。