Sprite Kit, the 2D game framework from Apple, has some interesting new features in iOS 8 and OS X Yosemite. These include integration with Scene Kit, shader support, lighting, shadows, constraints, normal map generation and physics enhancements. Previously, I went through an introduction to Sprite Kit. This post will take a look at some of the new physics features, particularly improvements to physics bodies and physics fields.
Creating a Physics Body from a Texture
Sprite Kit now supports deriving the physics body of a sprite from its texture. This makes it easy to implement collisions that look more natural.
For example, notice in the following collision how the banana and monkey collide nearly at the surface of each image:
Sprite Kit makes creating such a physics body possible with a single line of code. Simply call SKPhysicsBody.Create
with the texture and size:
sprite.PhysicsBody = SKPhysicsBody.Create (sprite.Texture, sprite.Size);
Additionally, you can tune how the physics body is derived by passing in an alpha threshold, which defines the minimum alpha value a pixel must have to be included in the resulting physics body.
sprite.PhysicsBody = SKPhysicsBody.Create (sprite.Texture, 0.7f, sprite.Size);
Tweaking the alpha threshold like this fine-tunes the previous collision, such that the monkey falls over when colliding with the banana:
Physics Fields
Another great addition to Sprite Kit is the new physics field support. These allow you to add things such as vortex fields, radial gravity fields and spring fields to name just a few.
Physics fields are created using the SKFieldNode class, which is added to a scene just like any other SKNode. There are a variety of factory methods on SKFieldNode to create different physics fields. You can create a spring field by calling SKFieldNode.CreateSpringField()
, a radial gravity field by calling SKFieldNode.CreateRadialGravityField()
, etc.
SKFieldNode also has properties to control field attributes such as the field strength, the field region, the noise used to generate forces, and the amount of attenuation of field forces as you move away from the field.
For example, the following code creates a spring field and adds it to the scene:
SKFieldNode fieldNode = SKFieldNode.CreateSpringField (); fieldNode.Enabled = true; fieldNode.Position = new PointF (Size.Width / 2, Size.Height / 2); fieldNode.Strength = 0.5f; fieldNode.Region = new SKRegion(Frame.Size); AddChild (fieldNode);
You can then add sprites and set their PhysicsBody properties so that the sprites will be affected by the physics field, as the following code does when the user touches the screen:
public override void TouchesBegan (NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch; var pt = touch.LocationInNode (this); var node = SKSpriteNode.FromImageNamed ("TinyBanana"); node.PhysicsBody = SKPhysicsBody.Create (node.Texture, node.Size); node.PhysicsBody.AffectedByGravity = false; node.PhysicsBody.AllowsRotation = true; node.PhysicsBody.Mass = 0.03f; node.Position = pt; AddChild (node); }
This causes the bananas to oscillate like a spring around the field node:
Adding a different field is similar. For instance, the following code creates a radial gravity field:
SKFieldNode fieldNode = SKFieldNode.CreateRadialGravityField (); fieldNode.Enabled = true; fieldNode.Position = new PointF (Size.Width / 2, Size.Height / 2); fieldNode.Strength = 10.0f; fieldNode.Falloff = 1.0f;
As you can see, this results in a different force field, where the bananas are pulled radially about the field:
With the new features added to Sprite Kit in iOS 8, it’s now very easy to create interesting effects in 2D iOS and OS X games. Have fun!
The code from this post is available in my GitHub repo.
0 comments