#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 из вашего сообщения.