Getting Started

In order to follow this tutorial, you will need to set up an Apple developer account and download Xcode (the program used to build IOS apps). Xcode is, unfortunately, only available for Macs; if you have a Windows/Linux machine here is a website that may help you set up Xcode.

These next steps will walk through registering for a free developer account and installing Xcode. If you already have an account and Xcode, you can skip to the next section. In order to get started first visit developer.apple.com and click member center, then sign in with your Apple ID. Go to the Apple Developer Agreement Page and accept the agreement; you now have a free developer account! In order to upload your projects to the app store you will have to pay a 100$ annual fee.

Now that you have a developer account you have to install Xcode. Xcode is available via the Mac App Store. After you have installed Xcode launch the program and click on Xcode -> Preferences -> Accounts -> + and choose Add Apple ID. Login with the Apple ID that used to register for the developer account. Congratulations, you can now test your apps in an iPhone simulator or run them on your personal device!

Beginning the project

Now that you have registered for a developer account and installed Xcode, you can begin developing your first mobile game!

Launch Xcode and click on “Create a new Xcode project”.

Click on the “Game” template.

Enter in the name “Snake” (or whatever you’d like) for your game. Pick an organization name, if you have a website you can enter that backwards (com.gavinshrader), or you can simply use your name as an identifier. Ensure the language is set to “Swift” and the game technology is “SpriteKit”. Uncheck the 3 check boxes if they are selected.

Right click “Actions.sks” and move to trash. Go to GameScene.sks and click on the “Hello World” text then delete it. Go to GameScene.swift and remove all the prebuilt code so that your file matches the image below.

Create a new Swift file either by going to File -> New File and clicking on Swift File, or by right clicking your project folder (“Snake”) and selecting new file. Find the Swift File icon that is highlighted below, if it is not present type “Swift” in the filter bar. Enter in the name “GameManager” and ensure that your project (“Snake”) is selected under targets, click “Create” to create your new swift file.

Building the game’s menu

Before we begin coding, check to ensure that your project compiles after the changes you made in the last section. Select a device from the simulator list, click on the button where “iPhone 6” is, it will likely be labeled “Generic iOS device”. If you want to test on a physical device plug your iPhone in, give Xcode a few moments and then click on your device. After you have done this click on the triangular run button. If you chose a simulated device this screen should pop up:

If the screen shows “Hello World” ensure that you deleted the label by going to GameScene.sks, clicking on the label and then selecting delete.

We are finally ready to start building the game! When you begin a game it helps to layout your screens beforehand. In this game we will begin with a simple menu screen that shows the game title/logo. A play button will launch a gameplay screen with a game area and two labels for your current score and best score. When you die the end game screen will display with an option to play again.

In order to get our game running we first have to build a menu to begin the game. We will start by writing code to initialize a menu by adding the game title, a “best score” label and a play button. Open the GameScene.swift file and copy down all the code from below so that your file matches the image (Figure A).

//1

var gameLogo: SKLabelNode!

var bestScore: SKLabelNode!

var playButton: SKShapeNode! //2

initializeMenu() //3

private func initializeMenu() {

//Create game title

gameLogo = SKLabelNode(fontNamed: "ArialRoundedMTBold")

gameLogo.zPosition = 1

gameLogo.position = CGPoint(x: 0, y: (frame.size.height / 2) - 200)

gameLogo.fontSize = 60

gameLogo.text = "SNAKE"

gameLogo.fontColor = SKColor.red

self.addChild(gameLogo)

//Create best score label

bestScore = SKLabelNode(fontNamed: "ArialRoundedMTBold")

bestScore.zPosition = 1

bestScore.position = CGPoint(x: 0, y: gameLogo.position.y - 50)

bestScore.fontSize = 40

bestScore.text = "Best Score: 0"

bestScore.fontColor = SKColor.white

self.addChild(bestScore)

//Create play button

playButton = SKShapeNode()

playButton.name = "play_button"

playButton.zPosition = 1

playButton.position = CGPoint(x: 0, y: (frame.size.height / -2) + 200)

playButton.fillColor = SKColor.cyan

let topCorner = CGPoint(x: -50, y: 50)

let bottomCorner = CGPoint(x: -50, y: -50)

let middle = CGPoint(x: 50, y: 0)

let path = CGMutablePath()

path.addLine(to: topCorner)

path.addLines(between: [topCorner, bottomCorner, middle])

playButton.path = path

self.addChild(playButton)

}

Figure A

Compile your code and check that your device shows the image from above. Here is an explanation for what’s going on here, this may look like a wall of code, but it is easy to understand when you break it down.

1: We create variables for the logos/buttons. The “!” after the variable name means that we must initialize the variables, they cannot be empty or “nil”.

2: We call the “initializeMenu()” function once the game view is loaded. didMove(to: view: SKView) is the function that is called once our GameScene has loaded.

3: This is the intializeMenu() function that we wrote to create the menu objects.

4/5/6: Create the objects and add to GameScene by calling “self.addChild()”.

7: I chose to use SKShapeNodes for this project due to their simplicity, this is an alternative to creating your graphics in an image editor. This line of code creates a path in the shape of a triangle. Please note if you plan on building and publishing an app you should use SKSpriteNodes to load an image you have created, ShapeNodes can cause performance issues when used in large quantities as they are dynamically drawn once per frame.

8: Set the triangular path we created to the playButton sprite and add to the GameScene.

Playing the game

Now that we have a simple menu setup let’s get the play button working. First go to your GameManager.swift file and replace all the code with this so that it matches the image below (Figure B).

import SpriteKit class GameManager { }

Figure B

Copy the code below into your GameScene.swift file so that it matches the image below (Figure C).

//1

var game: GameManager! //2

game = GameManager() //3

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

for touch in touches {

let location = touch.location(in: self)

let touchedNode = self.nodes(at: location)

for node in touchedNode {

if node.name == "play_button" {

startGame()

}

}

}

} //4

private func startGame() {

print("start game")

}

Figure C

1: Initialize a GameManager object. More on this later… this will hold score data and manage the movement of the player.

2: Set the game variable to a new GameManager() object.

3: This function is called by the game engine every time a user touches the screen. Recall that the play button we created earlier has the name “play_button”. Using the name we can check if the user has touched a SpriteNode with the name “play_button”, once this happens we call the startGame() function from bullet point 4.

4: This function starts the game.

Ensure that your code works properly by running your app and clicking the triangular play button. If your touches are being properly measured then the console should display “start game” as noted in the image below (Figure D).

Figure D

If your console is not showing then go to the top bar and click on “Help”, in the search bar type “Console” and then click on “Debug Area > Activate Console”. We now have a working menu system and a play button, this is where we can really start to have some fun.

Loading the Game View

So we have a play button now that can trigger a function, what should we do? In order to show the game view we first have to hide the menu buttons. Add this line of code to hide your menu buttons with a simple animation. Your code should match the image below (Figure E).

//start the game

private func startGame() {

print("start game")

//1

gameLogo.run(SKAction.move(by: CGVector(dx: -50, dy: 600), duration: 0.5)) {

self.gameLogo.isHidden = true

}

//2

playButton.run(SKAction.scale(to: 0, duration: 0.3)) {

self.playButton.isHidden = true

}

//3

let bottomCorner = CGPoint(x: 0, y: (frame.size.height / -2) + 20)

bestScore.run(SKAction.move(to: bottomCorner, duration: 0.4))

}

Figure E

Figure F

1: Move the gameLogo off the screen and then hide it from view. The brackets after the SKAction run once the action completes. For instance if we run an SKAction of duration 10, the code inside the bracket would run after 10 seconds. Here is an example:

exampleNode.run(SKAction.move(by: CGVector(dx: 0, dy: 0), duration: 10) {

print("I am reached after 10 seconds")

}

2: Scale the playButton to 0; this action shrinks the button and then hides it from view.

3: Move the bestScore label to the bottom of the screen.

Your menu should now behave like this gif (Figure F) when you click the play button!

Now we are going to begin designing the actual “snake” part of this game, start off by adding these lines of code so that your code matches the image below (Figure G).

//1

var currentScore: SKLabelNode!

var playerPositions: [(Int, Int)] = []

var gameBG: SKShapeNode!

var gameArray: [(node: SKShapeNode, x: Int, y: Int)] = [] //2

initializeGameView() //3

private func initializeGameView() {

//4

currentScore = SKLabelNode(fontNamed: "ArialRoundedMTBold")

currentScore.zPosition = 1

currentScore.position = CGPoint(x: 0, y: (frame.size.height / -2) + 60)

currentScore.fontSize = 40

currentScore.isHidden = true

currentScore.text = "Score: 0"

currentScore.fontColor = SKColor.white

self.addChild(currentScore)

//5

let width = frame.size.width - 200

let height = frame.size.height - 300

let rect = CGRect(x: -width / 2, y: -height / 2, width: width, height: height)

gameBG = SKShapeNode(rect: rect, cornerRadius: 0.02)

gameBG.fillColor = SKColor.darkGray

gameBG.zPosition = 2

gameBG.isHidden = true

self.addChild(gameBG)

//6

createGameBoard(width: width, height: height)

}

Figure G

Figure G

1: New variables! We are creating a label to show the current score, an array of all the positions that the “snake” or player currently has, a background for our game view and an array to track the positions of each cell in the game view.

2: Call the initializeGameView() function.

3: Initializes the game view.

4: Add the current score label to the screen, this is hidden until we leave our menu.

5: Create a ShapeNode to represent our game’s playable area. This is where the snake will be moving around in.

6: Create the game board. This function initializes a ton of square cells and adds them to the game board.

Next we want to create an array of cells which we will use to render the snake and the points on the screen. Create the createGameBoard function from the code below so that it matches Figure H.