Модель обнаружения столкновений Cocos2d — лучше всего подходит для моего случая?

#objective-c #xcode #cocos2d-iphone #collision-detection #box2d

#objective-c #xcode #cocos2d-iphone #обнаружение столкновений #box2d

Вопрос:

Я создаю игру cocos2d для iPhone с большим количеством пуль и движущихся врагов и обнаруживаю столкновения между ними. Каждый спрайт может быть представлен кругом для целей столкновения. Я рассматриваю следующие варианты:

1) Простое обнаружение сферы

Я обнаруживаю это через регулярные промежутки времени:

 -(BOOL) isCollidingSphere:(CCSpriteExt*) obj1 WithSphere:(CCSprite *) obj2
{
    float minDistance = obj1.radius   obj2.radius;
    float dx = obj2.position.x - obj1.position.x;
    float dy = obj2.position.y - obj1.position.y;
    if (! (dx > minDistance || dy > minDistance) )
    {
        float actualDistance = sqrt( dx * dx   dy * dy );
        return (actualDistance <= minDistance);
    }
    return NO;
}
  

2) Box2d только для обнаружения столкновений

Я создаю тело Box2d для всех спрайтов, как показано в этом руководстве: http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone

Мой вопрос прост: если моим приоритетом является оптимизация, какой подход быстрее?

Спасибо!

Ответ №1:

Если все, что вам нужно, это проверки столкновений на основе расстояния / радиуса, вам не нужен физический движок.

Однако вам следует избавиться от sqrt. Прежде всего, вы используете функцию квадратного корня, которая работает с удвоениями. Для версии с плавающей точкой используйте sqrtf.

Чтобы полностью избавиться от квадратного корня, убедитесь, что ваши объекты сохраняют квадрат своего радиуса (radiusSquared = radius * radius). Таким образом, вам больше не нужно извлекать квадратный корень:

 -(BOOL) isCollidingSphere:(CCSpriteExt*) obj1 WithSphere:(CCSprite *) obj2
{
    float r1 = obj1.radius;
    float r2 = obj2.radius;
    float minDistanceSquared = r1 * r1   r2 * r2   2 * r1 * r2;
    float dx = obj2.position.x - obj1.position.x;
    float dy = obj2.position.y - obj1.position.y;
    float actualDistanceSquared = dx * dx   dy * dy;
    return (actualDistanceSquared <= minDistanceSquared);
}
  

Комментарии:

1. Ваш пример кода неверен: минимальное расстояние = r1 r2, минимальное расстояние в квадрате = r1 * r1 2 * r1 * r2 r2 * r2, А НЕ r1 * r1 r2 * r2. Если вы сохраняете radiusSquared, вам все равно понадобится 2 * r1 * r2, поэтому ваша идея неверна. (Я не уверен в sqrtf, я не программист Objective C, но я вижу ошибку в вашем коде, и ваша идея хранения квадратов радиусов просто неверна, поэтому -1 с моей стороны.)

2. Почему идея сохранения квадрата радиуса неверна? Sqrt — дорогостоящая функция, и это уменьшает потребность в ней.

3. О, подождите, извините, потому что вам нужно 2 * r1 * r2, я понимаю.

4. Сохранение квадрата радиуса действительно плохая идея, я исправил код для правильного вычисления minDistanceSquared. Я также забыл dx / dy. Код все равно должен быть быстрее, чем при использовании sqrtf, хотя это должно быть протестировано на реальном устройстве.

5. LearnCocos2D, я рад удалить это неприятное -1 из вашего сообщения.