我有圆形精灵,我需要检查它们是否与任何其他圆圈碰撞。我试过了:
public boolean collision(){
boolean collide=false;
if(spriteNum>0)
for(int x=0;x<spriteNum;x++)
if(yourSprite[spriteNum].collidesWith(yourSprite[x]))
collide=true;
return collide;
}
但这会在它周围创建一个矩形,从而将其抛弃。我可以使用距离公式手动计算两个精灵是否接触,但这似乎很费力,而且每个精灵都附有一个圆形物理体,这意味着中心不断移动(我不知道如何找到中心)。有什么想法吗?
正如Alexandru指出的那样,到目前为止,AndEngine不支持圆圈碰撞检测。最好的方法是自己实现它。他的解决方案工作正常(快速),但以防万一您需要更高的精度,我将发布另一个近似值:
// There is no need to use Sprites, we will use the superclass Entity
boolean collidesWith(Entity circle){
final float x1 = this.getX();
final float y1 = this.getY();
final float x2 = circle.getX();
final float y2 = circle.getY();
final float xDifference = x2 - x1;
final float yDifference = y2 - y1;
// The ideal would be to provide a radius, but as
// we assume they are perfect circles, half the
// width will be just as good
final float radius1 = this.getWidth()/2;
final float radius2 = circle.getWidth()/2;
// Note we are using inverseSqrt but not normal sqrt,
// please look below to see a fast implementation of it.
// Using normal sqrt would not need "1.0f/", is more precise
// but less efficient
final float euclideanDistance = 1.0f/inverseSqrt(
xDifference*xDifference +
yDifference*yDifference);
return euclideanDistance < (radius1+radius2);
}
/**
* Gets an aproximation of the inverse square root with float precision.
* @param x float to be square-rooted
* @return an aproximation to sqrt(x)
*/
public static float inverseSqrt(float x) {
float xhalf = 0.5f*x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i);
x = x*(1.5f - xhalf*x*x);
return x;
}
注意我不是快速 inverseSqrt 方法的作者,它适用于 Java(更准确地说是在 Android 中),因为它的浮点表示(请参阅 IEEE 754 浮点表示和 Java 浮点到字节表示)。
有关进一步的研究,请参阅:
- 雷神之锤3 快速逆 Sqrt 起源
- Java 中的快速逆 Sqrt 实现
由于Andengine中没有圆碰撞检测,因此唯一的方法是计算它们之间的距离
boolean collidesWithCircle(Sprite circle) {
float x1 = this.getX();
float y1 = this.getY();
float x2 = circle.getX();
float y2 = circle.getY();
double a = x1 - x2;
double b = y1 - y2;
double c = (a * a) + (b * b);
if (c <= this.getWidth()*this.getWidth())
return true;
else return false;
}
如果您使用的是物理世界,则可以使用 PhysicsFactory.createCircularBody() 方法创建圆形实体。