2012-06-20 4 views
0

У меня есть круглые спрайты, и мне нужно проверить, не сталкиваются ли они с каким-либо другим кругом. Я пробовал:Sprite сталкивается с кругом (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; 
} 

Но это создает вокруг него прямоугольник, который отбрасывает его. Я мог бы использовать формулу расстояния, чтобы вручную вычислить, если два спрайта находятся в контакте, но это похоже на налогообложение, и каждый спрайт связан с физическим телом круга, то есть центры постоянно движутся (и я не знаю, как найти центр) , Есть идеи?

ответ

1

Поскольку нет никакого круга обнаружения столкновений в 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; 
} 
0

Вы можете создавать круговые тела, если вы используете физический мир с помощью метода PhysicsFactory.createCircularBody().

2

Как указывает Александру, никакое обнаружение столкновения вокруг круга не поддерживается 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 floating point representation и Java float to byte representation).

Для дальнейших исследований, см:

Смежные вопросы