Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Using Swift and Sprite Kit for Physics and Particles

DZone's Guide to

Using Swift and Sprite Kit for Physics and Particles

· Mobile Zone ·
Free Resource

Swift comes bundled with Sprite Kit, which is a graphics rendering and animation infrastructure and includes, amongst other things, support for physics and particle systems. Inspired by this post from Thibault Imbert, I thought I'd attempt to create a scene containing a handful of bouncing balls, each emitting particles.

The first step is to create a game application project and define the game technology as Sprite Kit:


Our main class in this project defaults to GameScene.swift and, in this case, I override the didMoveToView() method to start adding the physics bodies. Each body is an instance of an SKShapeNode with a SKPhysicsBody attached. The SKPhysicsBody has properties such as friction, mass and restitution (the elasticity).

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

The next step is to create a particle system. Scene Kit has a set of predefined particle systems built in and these are added as a separate sks file via file -> new -> file -> resource -> SpriteKit Particle File. From there, you can select which preset to use:


Once the sks file is imported into the project, its properties can be edited with the SKNode Inspector under view -> utilities.

This editor sets the initial emitter properties, I can access all those properties at runtime using dot syntax, for example:

     emitter.particleLifetimeRange

Inside my loop to create the bouncing balls, I need to create an instance of the newly created emitter and link it to my ball. This is done by unarchiving the sks file and then casting to a SKEmitterNode:

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

    let emitter:SKEmitterNode = untypedEmitter as SKEmitterNode;

My initial thought was to add the emitter as a child of the shape, but this resulted in the entire particle field following the shape as it moved. What I needed to do was set the emitter's shapePosition to that of the shape's position and update the particlePosition with each frame.

In the creation loop, I populate an array with a tuple of the shape and emitter.

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

In ActionScript, I would have created a shape/emitter value object and populated a vector, but for these lightweight objects, a tuple is perfect.

Finally, I override the update() method (which works like enterFrame in AS3), I loop over my array of shape/emitter tuples to update the emitter's particlePosition with its shape's position.

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

After adding some touch handlers to update a radial gravity field to follow the touch point, we have a simple demo of some bouncing balls emitting basic particles.

The entire project is available in my Git Hub repository here.

Topics:
java ,mobile ,tips and tricks ,tools & methods ,particles ,physics ,swift ,sprite kit

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}