雪碧与圆圈碰撞(Android AndEngine)



我有圆形精灵,我需要检查它们是否与任何其他圆圈碰撞。我试过了:

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() 方法创建圆形实体。

最新更新