Over a million developers have joined DZone.

Using Swift and Sprite Kit for Physics and Particles

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

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:


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);

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.

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.

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

Published at DZone with permission of Simon Gladman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}