Статьи

Использование Swift и Sprite Kit для физики и частиц

Swift поставляется в комплекте с Sprite Kit , который представляет собой инфраструктуру рендеринга графики и анимации  и включает, помимо прочего, поддержку физики и систем частиц. Вдохновленный этой должности от Тибо Imbert , я думал , что попытка создать сцену , содержащую несколько прыгающие шарики, каждый из излучающих частиц.

Первым шагом является создание проекта игрового приложения и определение игровой технологии как Sprite Kit:

Наш основной класс в этом проекте по умолчанию — GameScene.swift, и в этом случае я перезаписываю  метод didMoveToView (), чтобы начать добавлять физические тела. Каждое тело является экземпляром SKShapeNode с прикрепленной SKPhysicsBodySKPhysicsBody  обладает такими свойствами, как трение , масса и реституции (эластичность).

   let shape = SKShapeNode(circleOfRadius: 20);
   [...]
   shape.physicsBody = SKPhysicsBody(circleOfRadius: 20);
   shape.physicsBody.friction = 0;
   shape.physicsBody.charge = 4;

Следующим шагом является создание системы частиц. Scene Kit имеет встроенный набор предопределенных систем частиц, которые добавляются в виде отдельного  файла sks через файл -> новый -> файл -> ресурс -> файл частиц SpriteKit . Оттуда вы можете выбрать, какой пресет использовать:

Как только файл sks импортирован в проект, его свойства можно редактировать с помощью инспектора SKNode в представлении -> утилиты.

Этот редактор устанавливает начальные свойства эмиттера, я могу получить доступ ко всем этим свойствам во время выполнения, используя точечный синтаксис, например:

     emitter.particleLifetimeRange

Внутри моей петли для создания прыгающих шариков мне нужно создать экземпляр только что созданного эмиттера и связать его с моим шариком. Это делается путем разархивирования файла sks и последующего приведения к SKEmitterNode :

     let untypedEmitter : AnyObject = NSKeyedUnarchiver.unarchiveObjectWithFile(NSBundle.mainBundle().pathForResource("MyParticle", ofType: "sks"));

    let emitter:SKEmitterNode = untypedEmitter as SKEmitterNode;

Моя первоначальная мысль состояла в том, чтобы добавить эмиттер как дочерний элемент формы, но это привело к тому, что все поле частицы следовало за формой при ее перемещении. То, что мне нужно было сделать, это установить shapePosition излучателя  в положение позиции фигуры и обновить частичку частиц с каждым кадром.

В цикле создания я заполняю массив кортежем формы и эмиттера.

     var shapeEmitterTuples : [(SKShapeNode,SKEmitterNode)];
    let shapeEmitterTuple = (shape, emitter);
    shapeEmitterTuples.append(shapeEmitterTuple);

В ActionScript я бы создал объект значения shape / emitter и заполнил вектор, но для этих легких объектов кортеж идеален.

Наконец, я перезаписываю метод update () (который работает как enterFrame в AS3), я зацикливаю свой массив кортежей shape / emitter, чтобы обновить  частичку частиц испозиций с позицией формы .

    for (shape, emitter) in shapeEmitterTuples
    {
       emitter.particlePosition = shape.position;
    }

После добавления некоторых обработчиков касания, чтобы обновить поле радиальной гравитации, чтобы оно соответствовало точке касания, у нас есть простая демонстрация некоторых прыгающих шариков, испускающих основные частицы.

Весь проект доступен в моем репозитории Git Hub здесь.