rphello101
rphello101

Reputation: 1771

Sprite collideswith circle (Android AndEngine)?

I have circular sprites and I need to check to see if they collide with any other circle. I tried:

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;
}

But that creates a rectangle around it which kind of throws it off. I could use the distance formula to manually calculate if two sprites are in contact, but that seems taxing and each sprite is attached with a circle physics body, meaning there centers are constantly moving (and I don't know how to find the center). Any ideas?

Upvotes: 0

Views: 2053

Answers (3)

Sergio R. Lumley
Sergio R. Lumley

Reputation: 81

As Alexandru points out, no circle collision detection is supported by AndEngine so far. The best way is to implement it yourself. His solution works fine (fast), but just in case you need a bit more precision, I will post another approximation:

// 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;
}

Note I am not the author of the fast inverseSqrt method, it works in Java (and more precisely in Android) because of its floating point representation (see IEEE 754 floating point representation and Java float to byte representation).

For further research, see:

Upvotes: 2

Khawar Raza
Khawar Raza

Reputation: 16120

You can create circular bodies if you are using physics world by using PhysicsFactory.createCircularBody() method.

Upvotes: 0

user874649
user874649

Reputation:

Because there is no circle collision detection in Andengine the only way is to calculate the distance between them

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;
}

Upvotes: 1

Related Questions