SpriteKit — Имитация физики — Часть 11

Моделирование физики в Sprite Kit осуществляется путем добавления физических тел (SKPhysicsBody) к сцене. Физическое тело моделирует физику для спрайта (дерева спрайтов) к которому оно подключено. Тело использует позицию и ориентацию спрайта. Каждое физическое тело имеет ряд характеристик, которые определяют, как происходит моделирование физики в нем. К ним относятся такие свойства физического объекта как, например, его масса или плотность или скорость. Эти характеристики определяют, как тело движется, как на него влияют силы в симуляции, и как оно реагирует на столкновения с другими телами. Каждый раз, когда сцена расчитывает новый кадр анимации, она имитирует эффекты сил и столкновений спрайтов с физтелами. SpriteKit вычисляет окончательную позицию, ориентацию и скорость для каждого физического тела. Затем, сцена обновляет положение каждого соответствующего спрайта.

Итак, для использования физики в вашем проекте, вы должны:

— Прикрепить SKPhysicsBody к узлам на сцене.
— Настроить свойства физических тел.
— Определить глобальные характеристики симуляции физики на сцене, такие как гравитация.
— В случае необходимости, установить скорость физических тел на сцене или примените к ним силы или импульсы.
— Определить, как тела на сцене взаимодействуют, когда они вступают в контакт друг с другом.
— Оптимизировать имитации физики, ограничить количество вычислений и т.п.

Кстати, Sprite Kit использует Международную систему единиц СИ (метры, килограммы…)

SKPhysicsBody
Есть три вида «физических» тел:
— Динамическое тело — имитирует физический объект с объемом и массой, которые могут быть затронуты силами и столкновениями в системе. Используйте динамические тела для спрайтов, которые должны передвигаться и сталкиваются друг с другом.

— Статическое тело — аналогично динамическому, но его перемещения не зависят от сил или столкновений. Однако, поскольку оно по-прежнему имеет объем, другие объекты могут отскакивать от него или взаимодействовать с ним. Используйте статические тела спрайтов, которые занимают много места на сцене. Например, вы можете использовать статическое тело для стен в лабиринте.

Статические и Динамические тела можно применять к любым спрайтам. Также эти тела можно включать и отключать на ходу. Например, в игре Happy Airjet (из предыдущих глав) физтело самолета имеет динамический режим пока не столкнется с облаком, после этого включаем статический режим [planeBody setDynamic:NO] для того, чтобы самолет спокойно упал вниз и не сталкивался с остальными объектами.

— EDGE — это не тело, это граница и все взаимодействия происходят с границами объекта или вообще являются некими границами на сцене. Например невидимая стена или полый объект в котором есть стенки и выход. Ниже на картинках будет все понятнее.

body_edge

Используйте форму физтела, которая соответствует его графическому представлению
В большинстве случаев, физтело должно иметь размер и форму, повторяющее визуальный образ спрайта. При написании Happy Airjet в предыдущих главах, я упоминал об этом. Пример на рисунке ниже, я набросал примерно как можно организовать форму физтел:

Bodys

Тем не менее, при выборе формы для вашего физического тела, не обязательно быть чрезмерно точным. Более сложные формы требуют кропотливой работы, чтобы смоделировать правильное тело. Когда будете задавать форму физтела, помните:
1. Круглая форма наиболее простая в обработке, а значит наиболее эффективная
2. Многоугольник — наиболее неэффективная форма тела, поскольку съедает много ресурсов при обработке

С границами же все также, прямоугольники или линии наиболее просты в обработке, а значит эффективны в обработке. Разнообразные петли же, наоборот сложны и неэффективны.

Примеры:

Круглое тело:

    SKPhysicsBody *airjetBody=[SKPhysicsBody bodyWithCircleOfRadius:30 center:CGPointMake(0, 0)];

Прямоугольное тело:

    SKPhysicsBody *airjetBody=[SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(50, 100) center:CGPointMake(0, 0)];

Многоугольное тело:

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 10, 15);
    CGPathAddLineToPoint(path, NULL, 35, 40);
    CGPathAddLineToPoint(path, NULL, 60, 70);
    CGPathAddLineToPoint(path, NULL, 10, 15);
    
    SKPhysicsBody *airjetBody=[SKPhysicsBody bodyWithPolygonFromPath:path];

Edge — прямоугольная граница вокруг сцены:

    SKPhysicsBody *frame=[SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

Edge — просто линия, типа стена:

        SKPhysicsBody *wall=[SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(100, 100)];

Пока все. В создании SKPhysicsBody ничего сложного нет. В следующей главе будем конфигурировать тела, это будет сложнее. Пишите комменты.

  • Онотоле

    Вот бы еще все твои уроки перевести на Swift, цены бы им не было!!! А то пока дельных мануалов нет 🙁

    • floMaster

      Перевожу на свифт уже