In this tutorial I will be showing you how to create your very own record player in Sprite Kit using Swift. This is a small section of an app that I am building for a band that is set to be released in a month or so. Keep an eye on the blog to keep updated with that. Here’s what our project is going to look like when we’re done.

photo: Inner Monk Design

When you press the play button, the disk begins to spin and our music begins playing. After, a pause button will appear that allows you to stop the disk and pause the music. Sound complicated? Don’t worry, it’s very simple and will teach you a whole lot about Sprite Kit and how to get the most out of Apple’s wonderful frameworks. Just a small disclaimer, this tutorial is written for intermediate programmers, as I’m not going to explain every last thing, mainly to keep things short and sweet. That shouldn’t scare away new programmers or those new to Swift, as the material won’t be too difficult to understand. Don’t be afraid to ask me to explain something in the comments if you like.

First things first, let’s create a new project in Xcode. Choose Game from the initial screen and then set the title to whatever you like, I’ll be using RecordPlayer. Also, you can choose iPhone from the devices dropdown as I did, and make sure Sprite Kit is used.

Let’s add the two files that we’ll need from the outside world to the project. Visit www.bensound.com and download the song file there, then add it to your project, making sure that the “copy files if needed” is checked and the file is added to your project’s target. Then, go ahead and download the image of a record I have below and add it to your Images.xcassets folder.

photo: Disk

Next, we’re going to jump right into the GameScene.swift file of your project. Right at the top, before where your class starts, we’re going to add a few variables that we’re going to use throughout the project. Also, we’re going to add the AVFoundation import so we can support our AVAudioPlayer. The code for this is below:

import AVFoundation

//Variable setup
var disk = SKSpriteNode(imageNamed: "disknew001.png")
var playButton = SKLabelNode(fontNamed:"Helvetica")
var pauseButton = SKLabelNode(fontNamed:"Helvetica")
let action = SKAction.rotateByAngle(CGFloat(-M_PI), duration:1.5)

//Song setup
let song1 = NSBundle.mainBundle().pathForResource("bensound-funkyelement", ofType:"mp3")
let fileURL1 = NSURL(fileURLWithPath: song1!)
var player1 = AVAudioPlayer(contentsOfURL: fileURL1, error: nil)

This should be self-explanatory, as we’re just declaring our variables – the disk, the two button labels, and the disk’s spinning action. The player setup may seem a bit strange, but this is how you set up an AVAudioPlayer in Swift.

Now in your didMoveToView function, we’re going to add our background color, the disk, and the play button to the scene. We also set up the pause button, but we don’t add it just yet as we want that to be shown only after that play button has been pressed. This is a concept you should get used to, as there multiple times throughout any given project where you want a button to only show after another button has been pressed. The code for all of this is below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Background Color
scene?.backgroundColor = UIColor.whiteColor()

//Disk
disk.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) + 25)
disk.yScale = 1.00
disk.xScale = 1.00
disk.name = "disk"
self.addChild(disk)

//Play Button
playButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 250)
playButton.name = "Play"
playButton.text = "Play"
playButton.fontSize = 40
playButton.fontColor = UIColor.blackColor()
self.addChild(playButton)

//Play Button
pauseButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 250)
pauseButton.name = "Pause"
pauseButton.text = "Pause"
pauseButton.fontColor = UIColor.blackColor()
pauseButton.fontSize = 40;

Almost there ya’ll!

If you run your project now, you will see everything on the screen, but nothing will happen just yet when you press the play button. Let’s change that!

Down below your didMoveToView function, you’ll notice a touchesBegan function. This function exists to handle touches on variables we declared earlier. That’s why we named each of our variables. What we’re going to do here is respond to two different touches. The play button is going to make the disk spin, then it removes itself from the view and adds the pause button to the screen. After it’s done doing that, it’s going to start playing the music we prepared earlier. Again, the music set up may seem weird at first, but you’ll get used to creating AVAudioPlayers for all different types of reasons.

The pause button acts similarly to the play button, but it does things that a pause button should do. First, it stops the disk from spinning, removes the pause button from the screen, and then adds the play button back to the mix. Then finally, we pause the music until the next time the play button is pressed. You can see all the code for this right here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
for touch: AnyObject in touches {
  let location = touch.locationInNode(self)
  let touchedNode = self.nodeAtPoint(location)

  if touchedNode.name == "Play" {
      disk.runAction(SKAction.repeatActionForever(action))
      playButton.removeFromParent()
      self.addChild(pauseButton)

      //Set up and start the player
      player1.prepareToPlay()
      player1.play()
  }

  if touchedNode.name == "Pause" {
      disk.removeAllActions()
      pauseButton.removeFromParent()
      self.addChild(playButton)

      //Pause the player
      player1.pause()

  }

}

Screen Shot 2015-04-01 at 1.57.15 AM

That’s it! I told you it was easy. Now you have a real-deal record player right on your iPhone! Take what you learned here and apply it to your own apps and ideas. Here’s the link to the GitHub files in case you want to check out the code for yourself. As always, any feedback or questions are welcome. Thanks for joining me.