Tag: SpriteKit

Keep the Player on the Screen with SpriteKit Constraints

If you have a game where the scene doesn’t scroll, you want to prevent the player from moving off the screen. SpriteKit constraints provide a nice way to keep the player on the screen at all times.

Creating a Position Constraint

Start by creating a range that specifies the lower and upper limits for a sprite’s position. Call the SKRange initializer and supply the lower and upper limits. The initializer for SKRange takes floating point values. You will get a compiler error if you supply integers, such as the following:

After creating the range, call the SKConstraint class function positionX or positionY and supply the range.

The SKConstraint class has two positionX functions. One version constrains the sprite’s x value. The other version constrains both the x and y values. I’m not sure why they didn’t name the other version positionXY.

After creating the constraints, add them to the sprite by setting its constraints property. The constraints property takes an array of constraints.

Constraint Example

Suppose you have a brick breaking game where the paddle moves horizontally. The following code creates a constraint to prevent the paddle from moving off the screen:

Keeping the Sprite Completely on the Screen

One issue with the code listing from last section is half of the paddle may move off the screen. If you want to prevent any part of the sprite from going off the screen, you must account for the sprite’s size when setting the range.

Why can part of the sprite move off the screen with the code from the last section? SpriteKit uses the center of the sprite to determine its position. Suppose the player moves left. The sprite will keep going left until the center of the sprite reaches zero. Because the sprite can move left until its center is at the left edge of the screen, half the sprite can move off the screen.

To keep the sprite completely on screen, set the lower range limit to be half the sprite’s width (or height for vertical constraints). Set the upper limit to be the edge of the screen minus the lower limit.

The following code prevents any part of the paddle from moving off the screen:

Full Example

I have an example on GitHub that demonstrates keeping the player on the screen in a simple game.

The placePlayer function in the GameScene class has the code to keep the player from going off the screen.

Generating Random Numbers in Swift with GameplayKit

Many games have a need to generate random numbers. If you are making an iOS game with SpriteKit, the GameplayKit framework has classes for generating random numbers.

Generating random numbers has two steps.

  1. Create a random number generator
  2. Generate a random number

Creating a Random Number Generator

Create an instance of GKRandomDistribution, which is GameplayKit’s class for generating random numbers. Supply the low and high values to define the range of numbers the generator can generate.

The following code demonstrates how to create a random number generator for rolling a die:

Generating a Random Number

After creating the random number generator, you can use it to generate random numbers. Call the generator’s nextInt function to generate a random number.

The following code simulates a die roll:

Example

I have a simple game prototype on GitHub that spawns objects at random starting points.

The spawnFood function in the GameScene.swift file has the random number code.

Adding a Texture to a Sprite in SpriteKit

When you add a sprite to a SpriteKit scene from the scene editor, the only option is to create a sprite with a single color. A sprite with one color is OK for prototyping. But you’re going to eventually need to use real images for your sprite. Textures are the way to apply an image to a sprite so it looks like a spaceship, car, person, animal, or whatever your game needs. In this article you’ll learn how to add textures to your SpriteKit project and apply a texture to a sprite.

Add the Images to the Project

The first step to using textures is to add the texture images to the project. Add the images to the asset catalog.

  1. Select the Assets.xcassets folder on the left side of the project window.
  2. Click the Add button, which is at the bottom of the list of assets in the catalog.
  3. Choose Import from the menu that opens when you click the Add button to add an image.

You can also choose Image Set from the menu. Drag the image to the 1x, 2x, or 3x image well. What do 1x, 2x, and 3x mean?

  • A 1x image is for non-retina screens. Only very old iOS devices have non-retina screens.
  • A 2x image is for retina screens.
  • A 3x image is for super-retina screens on newer iOS devices.

Supporting 1x, 2x, and 3x means you need three copies of each image. If you have a texture image that is 128 by 128 pixels, you must supply the following images:

  • The 128 by 128 pixel version for 1x
  • A 256 by 256 pixel version for 2x
  • A 384 by 384 pixel version for 3x

Assign a Texture to a Sprite

After adding the texture images to the asset catalog, you can apply a texture to the sprite.

  1. Open the scene (.sks file) that contains the sprite.
  2. Select the sprite.
  3. Open the attributes inspector.
  4. Choose the texture from the Texture combo box.

Now the sprite looks like the texture image instead of one solid color.

You can create a sprite in code and use the texture image by calling the SKSpriteNode initializer and supplying the name of the image as the imageNamed: argument.

The name of the image must match the name in the asset catalog.

Introducing Xcode’s Scene Editor

In the Creating Your First SpriteKit Project article you created a game project in Xcode and removed Apple’s boilerplate code. Now you’re ready to start adding content to your game.

Xcode’s scene editor is the tool most SpriteKit games use to add game content. Use Xcode’s scene editor to do things like build your game’s levels, design your game’s main menu, and create an end of game screen.

Opening the Scene Editor

Select a file with the extension .sks from the left side of the project or playground window to open the scene in the scene editor. If you create a Game project or playground in Xcode, Xcode includes a scene file, GameScene.sks.

Finding Game Scene File

Scene Editor View

When you open an empty scene file, the scene editor looks like the following screenshot:

SceneEditorViewHighlighted

The scene editor has the following areas:

  • Scene graph view
  • Canvas
  • Bottom bar
  • Action editor view

The scene graph view shows a hierarchical list of the items in the scene. The scene graph view is the easiest way to select an item so you can move it, resize it, or edit its attributes.

The canvas is where you lay out the scene.

The bottom bar has the following controls:

  • Buttons to show and hide the scene graph view and action editor view.
  • An Animate button to play an action.
  • A button to control the playback speed.
  • Buttons to zoom the canvas in and out.

Unless you have a huge monitor it can be tough to see the whole canvas to see how large the scene is. Zooming out lets you see the bounding rectangle of the scene.

ZoomedOutCanvasHighlighted

The action editor view lets you edit SpriteKit actions in the scene editor. You’re more likely to create SpriteKit actions in code.

Drag an action from the Library to the action editor. Click the Animate button in the bottom bar to play the action. Select an action from the timeline and press the Delete key to remove an action.

Adding Items to a Scene

The first step to adding an item to a scene is to open the object library, which contains all the items you can add to SpriteKit scenes. Click the Add (+) button in the project window toolbar to open the object library.

If you are running Xcode 10, there is an Object Library button instead of an Add button in the toolbar.

ObjectLibraryButtonHighlighted

Holding down the Option key when you click the Add button keeps the object library window open.

ObjectLibrary

To add an item to the scene, select the item you want to add from the object library and drag it to the canvas or the scene graph view. Unless you want the item to be in the center of the scene, I recommend dragging to the canvas.

Moving and Resizing Items

Select the item from the scene graph view or the canvas. The following screenshot shows a selected sprite node in the canvas:

SelectedItem

To move the item, click the white circle in the center, hold the mouse button down, and drag the item. To resize an item, click one of the eight blue dots, hold the mouse button down, and move the mouse in the direction you want to resize.

Renaming Items

Double-click an item in the scene graph view to rename it.

Making Other Changes to Items

Use the attributes inspector to make other changes to items. In Xcode choose View > Inspectors > Show Attributes Inspector to show the attributes inspector. What the attributes inspector shows depends on the type of item you are inspecting. The following screenshot shows the attributes inspector for a sprite node:

AttributesInspector

Some attributes you can specify for a sprite node include the following:

  • Name
  • Parent
  • Texture image
  • Position
  • Size
  • Anchor point
  • Color
  • Scale
  • Physics body

If you’re going to access a sprite node from your code, it’s important to remember the name you gave it in the scene. If the names don’t match, your code won’t be able to find the node.

Exercise: Add a Sprite to the Scene

As a learning exercise, add a sprite (the Color Sprite item in the Library) to the scene. Run the project and you should see the sprite on the screen.

Creating Your First SpriteKit Project

Xcode playgrounds are good for prototyping game ideas, but if you want to get a SpriteKit game on your iPhone or iPad, you must create a project in Xcode. This article guides you through creating a SpriteKit project in Xcode.

Choose the Game Project Template

Launch Xcode and choose File > New > Project to create a project. When you choose File > New > Project the New Project Assistant opens.

NewProjectAssistantStep1

At the top of the New Project Assistant is a list of platforms: Multiplatform, iOS, macOS, watchOS, tvOS, and Other. Multiplatform, iOS, macOS, and tvOS all have game project templates. You can choose iOS, but I’m going with Multiplatform in this article for the following reasons:

  • On some versions of Xcode, the iOS game project template is missing a launch storyboard. The missing storyboard causes the scene to be much smaller than the screen size, giving you black bars on the edges of the screen. Read the Make Background Fill Entire SpriteKit Scene article for a way to work around the bug.
  • I find that building and testing works better on the Mac than the iOS simulator.
  • Having a Mac target will make things easier for those of you who don’t have a paid developer account. With a free account you must create a provisioning profile every week and reinstall your games on the device.

After choosing the platform, select the Game template. Click the Next button to move to the next step.

Configure the Project

After clicking the Next button, it’s time to configure the project.

NewProjectAssistantStep2

Enter the name of the project in the Product Name text field. The project name is also the name of the game.

Choose your developer team from the Team menu. If you do not have a development team, choose None.

Enter an organization identifier in the Organization Identifier text field. The organization identifier takes the following form:

If you don’t have a company name, replace CompanyName with your name.

Choose Swift from the Language menu.

Choose SpriteKit from the Game Technology menu.

If you chose the Multiplatform game project, there will be checkboxes to include the following platforms: iOS, watchOS, tvOS, and macOS. I selected iOS and macOS because I don’t have an Apple Watch or an AppleTV. Click the Next button.

Finish Creating the Project

The final step is to choose a location to save the project on your Mac. Click the Create button to finish creating the project.

In the save panel you should see a checkbox to create a git repository for the project. This is a matter of personal preference. If you clicked the Create button and want to create a git repository, choose Source Control > New Git Repositories to create a git repository for the project.

The Project Contents

The project navigator on the left side of the project window shows the project’s contents. The following image shows the project navigator for a Multiplatform SpriteKit game with iOS and Mac app targets:

ProjectNavigatorAtStart

You can see there’s a Shared folder that has the files for both the iOS and Mac versions of the project. Beneath the Shared folder are folders for the iOS version and the Mac version.

The two files you are going to use in this article are the two GameScene files.

Changing the Deployment Target (Optional)

The deployment target is the earliest operating system version (iOS, macOS, tvOS, or watchOS) that can run the game. Xcode defaults to using the version of the SDK that comes with the version of Xcode you’re using. Apple hasn’t added anything to SpriteKit since iOS 11 so you can set the iOS deployment target to iOS 11 and the macOS target to macOS 10.13 without doing any damage.

Select the project file from the project navigator to open the project editor. Select the project from the project editor. Use the combo boxes to set the deployment target.

SetDeploymentTarget

Run the Project

Let’s run the project. If you created a Multiplatform game project, you must choose which version of the project to run. At the top of the project window above the editor is a path control with two sections.

PathControl

The left section has the name of the project followed by the platform, macOS in the screenshot. Click that section to choose the version to run. Connect an iOS device to your Mac and choose the device from the jump bar to run the project on a device. Otherwise choose a simulator from the jump bar to run the project in the iOS simulator.

Click the Run (Play) button in the project window toolbar to run the project. A Hello, World label appears on the screen. Clicking in the window creates a spinning object. Dragging creates a line of spinning objects.

Remove Apple’s Boilerplate

You’re not going to need the label or the spinning objects in your game. So the next step is to remove the label and the spinning objects.

Select the GameScene.sks file to open the scene editor. Select the label from the canvas or the object list next to the canvas. Press the Delete key to remove the label from the scene.

Now there’s a lot of code to remove from the GameScene.swift file. You must remove all the code that accesses the label and the spinning nodes. Start by removing all the code from the setUpScene function so it looks like the following:

Next, remove the makeSpinny function.

Next, edit the touchesBegan, touchesMoved, touchesEnded, and touchesCancelled functions so they look like the following:

If you have a Mac app target, remove the code inside the mouseDown, mouseDragged and mouseUp functions.

Run the Project Again

Click the Run button to make sure there are no build errors. The project should run and show a blank window.

Now you’re ready to start adding your own stuff to the project.

Adding New Files to the Project

When you create a SpriteKit game project, Xcode includes a scene. But most games require more than one scene so you’ll be adding files to your project.

Choose File > New > File to add a new file to your project. The files you will add to SpriteKit projects are in the Source and Resource sections of the New File Assistant. The source code files you will create are Swift files and Cocoa/Cocoa Touch class files. You would create a Cocoa/Cocoa Touch class file when creating a subclass of a SpriteKit class.

The Resource section has the following files for SpriteKit projects:

  • Asset catalog
  • SpriteKit action
  • SpriteKit particle file
  • SpriteKit scene
  • SpriteKit tile set

If you created a Multiplatform game project, make sure you add the files to all of the project’s targets.

Adding Existing Files to the Project

To add files you’ve already created to a project, choose File > Add Files to ProjectName. An Open panel opens. Navigate to where the files are, select them, and click the Add button.

If you add a file of folders to the project, you have the option of creating groups or folder references. Create a group if you need to edit the files in Xcode. If you are adding a folder of source code files, create a group.

Create a folder reference if you don’t need to edit the files in Xcode. If you are adding a folder of sound or image files, create a folder reference.

Make Background Fill Entire SpriteKit Scene

I have seen many questions lately on Stack Overflow from people creating an iOS SpriteKit game project and having black bars on the edges of the screen.

The cause of the issue is a bug in Xcode’s iOS game project template. When you create the project, the project does not include a storyboard for the launch screen. If you create a multiplatform game project, you will see a file called LaunchScreen.storyboard in the project navigator. This storyboard file is missing in the iOS template. Without a launch screen storyboard, the scene size defaults to 320 by 480 pixels, giving you black bars on the edges of the screen.

To fix the issue you must set a storyboard as the launch screen file. Fortunately the iOS game project has a main storyboard to use as the launch screen file. To set the launch screen file, perform the following steps:

  1. Select the project from the project navigator on the left side of the project window to open the project editor.
  2. Select the app target from the target list in the project editor.
  3. Click the General button at the top of the project editor.
  4. Choose Main from the Launch Screen File combo box in the App Icons and Launch Images section.

SetLaunchScreenFile

Tap to Move in SpriteKit

Many iOS games use tap to move. Tap on the screen, and the player character will move to where you tapped.

Use the SpriteKit action moveTo to add tap to move. Supply the destination location and the time interval (in seconds). When you run the action, the sprite will smoothly move to the destination over the time interval.

The speed the sprite moves depends on the distance between the sprite and the tap. The longer the distance, the faster the sprite moves.

Avoid Subclassing SKSpriteNode

When I see SpriteKit questions on Stack Overflow, I notice a common problem people make. They make every visible entity in their game, such as the player and enemies, a subclass of SKSpriteNode. They also add a property to the subclass for the sprite node.

Subclassing SKSpriteNode and having a property of SKSpriteNode is redundant. If you have a property for the sprite, you don’t need to subclass SKSpriteNode. If you have a SKSpriteNode subclass, an instance of the subclass has all the components of SKSpriteNode. You don’t need the property.

In 99 percent of cases, avoid subclassing SKSpriteNode and add a property for the sprite node to your class or struct. Prefer composition to inheritance.

A player has a sprite node along with other properties that depend on your game (score, number of lives, health, etc.). A player is not a sprite node.

Handling Touches in a SpriteKit Game

One thing most iOS games must do is handle touch input from the player. If you use SpriteKit, handling touch input isn’t too difficult.

When you create a SpriteKit project or playground, the GameScene.swift file includes the following functions to handle touch input:

  • touchesBegan
  • touchesMoved
  • touchesEnded
  • touchesCancelled

The two functions you’ll use the most are touchesBegan and touchesMoved. You use touchesBegan to handle taps and use touchesMoved to move a sprite with your finger.

Determining What Was Touched

Use the location property to determine where the touch occurred. Call the atPoint function to determine what SpriteKit node was touched.

Once you know what SpriteKit node the player touched, you can do whatever you need to do with the node, such as move it, hide it, or highlight it.

Example Playground

I have a SpriteKit playground that lets you drag a sprite around the screen.