Does the tedious task of manually positioning everything in your game’s levels via code make you think you’ll break out in hives?
Worry no more – creating levels can be easy, fun and done with almost no contact with code. In this tutorial, you’ll learn just how to do just that using the powerful Sprite Kit scene editor.
In this Sprite Kit scene editor tutorial, you’ll create a fancy level for a spooky 2D zombie game named Fear the Dead. In the process, you’ll learn:
- What the scene editor is, how to navigate its layout and how you can add sprites to it.
- How you can use file references to reuse an SKScene.
- How to create a dark vibe using an SKLightNode.
- How to work with the new iOS 9 SKCameraNode.
- How to use the Action Editor to add animations to nodes without any code.
- How to use SKAudioNodes to create positional audio.
- How to survive a zombie apocalypse. :]
As you can see we have a lot to cover, so let’s get started!
Note: This Sprite Kit scene editor tutorial assumes that you already know the basics of Swift as well as the basics of the Sprite Kit. If you’re new to Swift, check out the Swift Apprentice book series, and if you’re new to Sprite Kit, check out the Sprite Kit Swift 2 Tutorial for Beginners tutorial.
Getting Started
In order to get you up and running without a bunch of noise, download the starter project for this tutorial here. It’s based on the SpriteKit Game template and already has some of the more tedious work done for you.
This way you can focus on creating an awesome zombie-rich environment level without tinkering with all the underlying logic. The starter project comes with:
- The logic needed for actually playing the game, like the logic for moving around the player and the zombies, as well as logic for when these collide.
- All the sounds and images you need.
- A MenuScene.swift that denotes the end of a game and also gives the option to restart the game.
Once you’ve downloaded and unzipped the project, open it in Xcode and build and run. After the splash screen intro, you should see the following appear on your device or in the simulator:
As you can see, there’s not much to play with yet, so let’s get started with the scene editor, shall we?
Getting Started with the Scene Editor
First, a bit about the game you’re building. Fear the Dead leads you on a nail-biting adventure where you have to escape from one room into another without being bitten by infected, nasty zombies. For a full-blown game, there would be tons of exciting levels.
Creating levels in code, however, can be very tedious and cumbersome, and could lead you to become one of the zombies you’re trying to escape. This is where the scene editor, a built-in Xcode tool designed to help you build levels without having to write everything in code, comes in.
Setting up the Scene
If you look in the project navigator you should see the file GameScene.sks. Select this file and you’ll see a new editor panel that shows a gray background as shown in the screenshot below:
Now, click the – button in the lower mid-right corner until you see a yellow rectangle appear. It serves as the boundary of your scene and all of your level’s components will be placed within. Alternatively, you can also pinch your trackpad to zoom in and out. You should now have a view similar to:
When creating a new scene, the default scene size is 1024 x 768 pixels, but you want your level to be a bit bigger. First, make sure you have the utilities editor open on the right-hand side, and select the Attributes Inspector.
If you do not see the utilities editor, simply click View\Utilities\Show Attributes Inspector and it should show itself. Next, change the dimensions of the scene to be 1080 x 1920.
Awesome! The scene is now ready for some components, so now you get to move on to looking at what you can actually add.
The Object Library
First, at the bottom of the utilities editor, select the Object Library.
The Object Library displays all the different objects you can drop onto your scene and configure. In this tutorial you’ll be working primarily with Color Sprites, but there many other objects to choose from, including:
- Shape Node: a special type of node that allows you to easily draw squares, circles and other shapes.
- Label: surely you’ve used a label in your games before, and this one is no different. However, this time you’ll be able to easily place it on the screen and edit it with a few clicks.
- Light: A very cool object you can add is a light, and by placing one on your scene you get a spotlight effect and have the option of making your other objects cast shadows. You’ll add a light later in the tutorial. :]
If you’ve used a SKSpriteNode or few in other games, then you’ll already be familiar with the configuration options that come with a Color Sprite. You can determine the node’s size, position, texture and even add a physics body to it.
Here’s the best part: No longer will you have to manage these in code nor re-run your program every few seconds to make sure everything is placed correctly. Quite neat, right?
Adding a Player Sprite
So how about you add a sprite to the scene?
First, drag and drop a Color Sprite onto the scene. You’ll notice that the sprite is selected by default and that a ton of properties are shown in the Attributes Inspector to the right.
Most of these properties should be recognizable. You can set the sprite’s name, position and anchor point, its parent node and the image file you want to use as the texture.
Make this sprite your player by adding the following properties:
- Change the sprite’s name to player
- Set its size to 75 x 75
- Set the texture to character
- Set its position by setting x to 200 and y to 1400
But wait! There’s more. If you look further down the Attributes Inspector, you’ll notice a section called Physics Definition where you can set the body type of your sprite. That way you do not have to define it in code. Awesome, right?
When it comes to body type, you have three different options to choose from:
- Bounding rectangle: This sets the body be the exact size of the node.
- Bounding circle: This sets the body be a circle with a diameter the size of the node’s longest side.
- Alpha mask: This makes Sprite Kit define the physical shape of your node based on the outline of the sprite’s texture image – unless you’re working with rectangles and/or circles, this is the most accurate one of the three.
Generally, you want to choose the simplest possible shape to get the desired accuracy you need for your game, as the more complicated the shape the higher the performance cost. For this game, you want collisions to be very accurate (after all, it’s hard enough to survive a zombie apocalypse), so you will choose alpha mask.
With the player node selected in the scene, click the Body Type menu and select Alpha mask. Next, uncheck Allows Rotation and Affected By Gravity as neither are needed for this tutorial. Finally, change the Category Mask to 1.
Note: The category mask will come into play later to detect contacts between the player and other nodes.
As previously mentioned, Fear the Dead will also use lighting to create a spooky feel. To ensure that the game is ready for this, set the Lighting Mask, Shadow Cast Mask and Shadowed Mask of the player to be 1.
One last thing before you build and run. Open GameScene.swift and add the following lines to didMoveToView(_:), right after the contact delegate has been set:
// Setup player player = self.childNodeWithName("player") as? SKSpriteNode |
With this simple line of code you have hooked up the player sprite from the scene editor to the actual code inside GameScene.swift. This works because you set the name of the sprite to “player” inside the Scene Editor earlier.
Easy, right? Build and run the game and you should now be able to move the player around by touching the screen. Oh yeah, progress!
Adding Zombie Sprites
Now that you know how to add a sprite it’s time to practice by adding some brain-hungry zombies to the mix! In this level, you’ll add five zombie sprites. Every zombie sprite will have a unique position but all will have the following properties:
- Name: zombie
- Texture: zombie
- Size: 50 x 50
- Lighting, Shadow Cast and Shadowed Mask: 1
- Body Type: Alpha mask
- Allows Rotation & Affected By Gravity: Disabled
- Category Mask: 2
- Contact Mask: 1
Now, add five zombie sprites with the following positions using the above properties.
- 1: (900, 1800)
- 2: (200, 800)
- 3: (900, 1100)
- 4: (150, 150)
- 5: (950, 550)
Done? Awesome! Your game scene should now look like this:
So, there is a little more coding to do. You didn’t actually think that you could get out of a tutorial with zero coding, did you?
Just like you did with the player, you need to add a few lines of code before these zombies will operate with the rest of the game. Open GameScene.swift, and add the following lines to didMoveToView(_:) right after the line where you set up the player:
// Setup zombies for child in self.children { if child.name == "zombie" { if let child = child as? SKSpriteNode { zombies.append(child) } } } |
These lines will find every child node with the name zombie and add them to an array of zombies – that sounds truly terrifying! This array will eventually move the zombies around the screen.
Build and run the game and the zombies should now be chasing you. Yikes! Hope you’ve been keeping up on your cardio.
Adding a Goal, Walls and a Background
All this running about is tiresome, and the zombies have you trapped. Your player might as well be the main course at a buffet as far as they are concerned.
It would be great to have a way to complete the level, don’t you think?
Go ahead and add a goal to the lower-right corner. Select a Color Sprite from the Object Library and drop it on the scene. Then add the following properties to the sprite:
- Name: goal
- Texture: goal
- Size: 50 x 170
- Position: x: 1055, y: 135
- Lighting, Shadow Cast, and Shadowed Mask: 1
- Body Type: Bounding rectangle
- Dynamic, Allows Rotation & Affected By Gravity: Disabled
- Category Mask: 3
- Contact Mask: 1
Just like before, you need to use this sprite in your code. Open GameScene.swift, and add the following lines to didMoveToView(_:) right after the lines where you set up the zombies:
// Setup goal goal = self.childNodeWithName("goal") as? SKSpriteNode |
Your game scene should now look like this:
When running the game, it’s hard to tell where the boundaries of the level are. In order to fix this you’ll need some walls around your level, in fact, you’ll need four walls with the following properties:
- Lighting, Shadow Cast, and Shadowed Mask: 1
- Body Type: bounding rectangle
- Dynamic, Allows Rotation & Affected By Gravity: disabled
Add the four walls using the above and customize them with these properties:
Wall 1:
- Texture: wall_50x1920
- Position: (25, 960)
- Size: 50 x 1920
Wall 2:
- Texture: wall_50x1700
- Position: (1055, 1070)
- Size: 50 x 1700
Wall 3:
- Texture: wall_1080x50
- Position: (540, 1895)
- Size: 1080 x 50
Wall 4:
- Texture: wall_1080x50
- Position: (540, 25)
- Size: 1080 x 50
Good job! Your game scene should now look as follows:
Last, but not least, add a background to the game scene. Select a Color Sprite from the Object Library and drop it on the scene. Add the following properties to the sprite:
- Texture: background
- Size: 1080 x 1920
- Position: (540, 960)
- Lighting Mask: 1
- Z-position: -1 (This layers the background behind all other nodes.)
Build and run the game. As you run around the level the walls should keep you in place – see if you can get to the goal before the zombies get to you.
Camera Positioning with SKCameraNode
Being able to view the whole level at once isn’t really the best experience. The player and the zombies look too small, and the game feels a bit too predictable. To fix this, you’ll just need to implement a camera node.
In iOS 9, Apple introduced a new class called SKCameraNode, which is an object used to specify a position in the scene from which it can render. Because the camera is a node, it can be moved just like any other node in the scene using actions, physics and so on. When a scene renders with a camera node, two things happen:
- The scene renders so that the origin of the camera node is placed directly in the middle of the scene.
- The inverse of the camera node’s xScale, yScale and zRotation properties are applied to all nodes in the scene.
What this means is that if, for example, the camera is moved 20 pixels to the right, then the scene is rendered as if everything else moved 20 pixels to the left.
Note: For a more in-depth description of the camera node, watch the WWDC 2015 talk What’s New in Sprite Kit. At about three minutes, you meet the SKCameraNode.
Adding a Camera to the Scene
So now you might be wondering if – possibly even dreading – the camera node is something you’ll have to create programmatically. The answer is, as you might expect, that you can create it using the scene editor. Whew!
Go to the Object Library, and locate the Camera node. Next, drag and drop it onto the scene on top of the player; it doesn’t have to be exactly on top as the camera’s position is updated in code. Open the Attributes Inspector, and change its name to be equal to camera and its scale to be equal to x = 0.5, y = 0.5, which is a quarter of the level’s total area).
If you were to run the game right now, the camera would not yet be activated because you need to tell the game scene to use the camera node as its camera.
Click outside the level’s boundary, and set its Camera property to be equal to the camera node you just created.
With this done, the camera should work as expected. Good job! Build and run the game and you should now only see a fourth of the level at any given time. The camera should also follow the player as you move it around.
File References
The scene editor allows you to reference content between different .sks (scene) files, meaning you can put together a bunch of sprites in a single scene file and then reference the file from another scene file.
You might wonder why you would need more than one scene, and there a couple of reasons:
- You can reuse the same collection of sprites in multiple different scenes, meaning you don’t have to recreate them over and over again.
- If you need to change the referenced content in all of your scenes, all you have to do is edit the original scene and the content automatically updates in every scene that references it. Smart, right?
Creating a Wall Scene
And now that you’ve read about it, you get to create some reusable components. For your game, it would be nice if you could add some walls, so kick off this part by adding a wall scene.
In the Project Navigator to the right, right-click the Scenes folder and from the pop-up menu, click New File…. Choose the iOS/Resource/SpriteKit Scene file template, and then click Next. Call the new file Wall.sks, and save it in the project’s folder.
Xcode automatically opens the newly created Wall.sks file and presents you with an empty editor window. In exactly the same way as before, your task is to resize the scene to your needs and add some sprites. Set the scene size to be 50 x 400 pixels.
Next, select a Color Sprite from the Object Library, drop it onto the scene and add the following properties to it:
- Texture: wall_50x400
- Position: (25, 200)
- Size: 50 x 400
- Lighting, Shadow Cast, and Shadowed Mask: 1
- Body Type: Bounding rectangle
- Dynamic, Allows Rotation, Affected By Gravity: Unchecked
That’s it – you now have a reusable wall!
Creating a Room Scene
Now that you have a reusable wall, you have the building blocks to create a new reusable room scene. Just like before, right-click the Scenes folder and select New File…. Choose the SpriteKit Scene file template, click Next, name the new file Room.sks and save it in the project’s folder. Next, set the scene’s size to be 400 x 400 pixels.
Now, instead of selecting Color Sprite, select a Reference from the Object Library. Drag and drop three reference objects onto the scene and give them the following properties:
Wall 1:
- Reference: Wall.sks – this is the .sks file you’re referencing
- Position: (0, 0)
Wall 2:
- Reference: Wall.sks
- Position: (350, 0)
Wall 3:
- Reference: Wall.sks
- Rotation: 270
- Position: (0, 50)
With this in place your room should look as follows:
Adding Rooms and Walls to the level
Go back to the GameScene.sks file and add a Reference object from the Object Library for each of the following:
Rooms (Reference / Position)
- Room.sks / (0, 1250)
- Room.sks / (680, 1250)
- Room.sks / (0, 650)
Walls (Reference / Position / Rotation)
- Wall.sks / (750, 1000) / 90
- Wall.sks / (1080, 650) / 90
- Wall.sks / (1080, 350) / 90
- Wall.sks / (350, 0) / 0
That was quite the task, but with these fancy reference objects added your amazing level should look like this:
Build and run the game to see if you can complete your newly created level. It’s harder than it looks…
Positional Audio using SKAudioNode
In iOS 9, Apple added a cool new feature to the Sprite Kit framework. It added what’s known as an SKAudioNode to allow you to add positional sound right in your Sprite Kit game.
Best of all, it’s super simple to set up.
All you have to do is specify the sound asset that should play back, as well as the node that will be the listener for positional audio coming from SKAudioNodes. With these in place, Sprite Kit automatically takes care of the rest, ensuring immersive, positional audio in your game.
Note: For a more in-depth description of the positional audio feature, watch the WWDC 2015 talk What’s New in SpriteKit. The SKAudioNode is introduced about five minutes in.
A quiet zombie just isn’t right, so let’s add some sound to make them more, um, undead-like. First, open the GameScene.swift file, locate the didMoveToView(_:) method, and add the following line underneath the setup of the player:
self.listener = player |
This sets the player as the node listening for positional audio.
Next, directly underneath, change the for-loop for adding zombies so that it looks like this:
for child in self.children { if child.name == "zombie" { if let child = child as? SKSpriteNode { // Add SKAudioNode to zombie let audioNode: SKAudioNode = SKAudioNode(fileNamed: "fear_moan.wav") child.addChild(audioNode) zombies.append(child) } } } |
Here you first create an audio node with the file named fear_moan.wav, and then add it to the individual zombie. This ensures that the moaning sound comes from the zombie and only the zombie itself.
Before running your code, try adding an audio node with the scene editor. Select GameScene.sks, open the Object Library and locate the Audio object. Drag and drop the object on top of the player and set its Filename to be fear_bg.mp3 and its parent to be player.
Easy, right?
Build and run the game, and you should be able to hear the zombies moaning and the background music. You should notice the zombie’s audio becoming richer, more centered and louder as it nears the player, which is the listener, and more one-sided and distant as it moves away.
For a more immersive feel, try wearing headphones.
Note: If you don’t hear the sounds, try letting the zombies get to you – they’re famished after all this running around. Truth be told, there’s an unknown bug that causes Sprite Kit to sometimes ignore the audio on launch.
Animations and Action-References
Wouldn’t it be cool if you could also add actions to nodes without having to write it all in code? Well, in Xcode 7 and later, you can! Apple added the Action Editor View so you can now drag and drop actions from the Object Library.
To open the Action Editor View, open GameScene.sks and find the arrow pointing upwards at the bottom of the Xcode window:
The action editor displays all the nodes in the scene and a timeline with rows that correspond to each node. If you’ve ever worked with animation or video software, you might be familiar with this user interface. You’re going to use the action editor to create a nifty zoom-out effect when you first launch the game.
Grab a Scale Action object from the Object Library and drop it onto the timeline track for the camera node. Next, locate the Attributes Inspector for the action up in the upper-right corner, and change the properties as follows:
- Start time: 0.3
- Duration: 1.5
- Timing Function: Ease in, Ease out
- Scale Amount: 5
With this action, you scale the camera by a factor of five, but you don’t want to change the scene-to-camera ratio you previously defined. Therefore, click the camera node in the scene and change it’s scale to be X = 0.1, Y = 0.1. After the action has been triggered, this will end up being 0.5, just like it was before.
Build and run the game, and you should see a cool zoom-out effect happening at launch.
Creating a Dark Vibe using SKLightNodes
Now, it was stated in the beginning that the game needed a spooky feel and so far it’s not very spooky. Change this by adding an SKLightNode to the player.
Because lights are nodes, you can move them or set them to perform actions. This means that if you add a light node to the player, it’ll follow the player around as it moves through the level – just the effect needed here.
The light node itself is invisible except for the effects you configure on the sprite nodes to interact with them.
Ah-ha!!! So that’s why I’ve had you setting the lighting, shadow cast and shadowed mask on all sprites throughout this tutorial. Each property has a different effect:
- Lighting Mask: The sprite is illuminated by the light with specular, diffuse and ambient lighting.
- Shadow Cast Mask: Whenever a sprite intersects with a light, a shadow projects past the sprite.
- Shadowed Mask: If the sprite is inside a shadow cast by a light, and the sprite has a lower z position than the light, the shadow affects how the sprite is lit.
Time to light it up!
In GameScene.sks, locate the Light object from the Object Library and drop it on top of the player sprite’s torch. Next, change the light’s parent node to be equal to player and change its Falloff to be equal to 2.
The Falloff denotes the exponent for the rate of decay of the light source, so the higher the number, the spookier and darker the level.
One more thing before you’re done: The outside of the level is still a very non-spooky gray color. To fix this, select the scene by clicking outside the boundaries of the level, and change its Color to Black.
That’s it! Now you’ve created a terrifying place where zombies run wild. Build and run the game, and you should see the following:
Note: At the time of writing, the iOS Simulator is having a hard time running the game without lag after implementing the light. I’d suggest running it on a device, where it shouldn’t cause any problems, or simply disable the light while you build your level.
Where To Go From Here?
Very well done! You’ve made it to the end of this tutorial and have now built a complete level for Fear the Dead. You have learned a ton of cool new features that you’ll be able to implement in your own projects going forward. You can download the final project here.
One of the best ways to make sure you remember what you’ve learned is to apply it in practice. For that reason, you should try and create another level or maybe even build your own game full of increasingly challenging levels.
We love seeing what you guys come up with, so make sure to share your creations in the comments below or on the forums.
If you want to learn more about Sprite Kit, you should check out our book 2D iOS & tvOS Games by Tutorials:
In this book we’ll teach you everything you need to know to make great games for iOS & tvOS – from physics, to tile maps, to particle systems, and even how to make your games “juicy” with polish and special effects.
Enjoy playing your new game; I look forward to hearing from you with comments below or questions on the forums. :]
The post Introduction to the Sprite Kit Scene Editor appeared first on Ray Wenderlich.