Learn iOS SpriteKit with Examples, Code Snippets and Video Tutorials

How to Loop a Sound Continuously Through Sprite Kit Scene Changes

How to Loop a Sound Continuously Through Sprite Kit Scene Changes

Sprite Kit includes a simple SKActions for playing sounds:  playSoundFileNamed , and although you could loop this, it is not meant for playing lengthy background sounds. Says who? Well, Apple. Here’s a quote from the official docs…

Creates an action that plays a sound. Use SKActionplaySoundFileNamed:waitForCompletion: only for short incidentals. Use AVAudioPlayer for long running background music.

So before we get into how to seamlessly loop a background sound using AVFoundation, let’s at least look at how to loop playSoundFileNamed…

Note that waitForCompletion equals true, so the duration of the action is the same as the length of the audio file.

So why doesn’t this work for a seamless background loop? Well if you want to change scenes, transitioning one scene out and another in, is going to cancel all SKActions on the outgoing scene.


AVFoundation with Sprite Kit and Notification Center Observers

Playing an endlessly looping background sound, which doesn’t get interrupted by scene changes, will require playing the audio from somewhere other than your SKScene. So lets do this from the GameViewController, the parent view controller which presents the app’s GameScene (the SKScene).

Change the top of your GameViewController to look like this…

So we’ve just added AVFoundation and declared an AVAudioPlayer variable named bgSoundPlayer.

Next up, we need to use the NotificationCenter to communicate from our GameScene class back up the chain of command to the GameViewController. Basically we add a notification observer (so our app begins “listening” for notifications) in the GameViewController, and then we will post notifications from the GameScene class (or any other class). Any time we post a notification, it will trigger a function to run in the GameViewController. It’s this function which will begin playing audio. We can also pass along data when we post a notification, which is how we’ll specify what audio file to play. So you could change the background audio anytime you want.

Add this to your viewDidLoad statement in the GameViewController class…

Take note of the part in quotes, these are the raw value names of the notification: “PlayBackgroundSound” and “StopBackgroundSound”.  After the #selector part, this is where we specify what functions are called when the notification is posted. Those functions are named playBackgroundSound and stopBackgroundSound.

So outside of the viewDidLoad function, add these two new functions. I’ll add notes within the code…

You’re done in the GameViewController.


Posting Notifications

From any other class, probably the GameScene class, you can now post a notification to call those functions in the GameViewController.

Line 1 – dictToSend creates a Dictionary with one key and one value. The key is fileToPlay, and MusicOrWhatever is the value. This would play a file named  MusicOrWhatever.mp3. So when you’re adding this code, you want the value to be whatever the name of your audio file is  MINUS the .mp3 extension.

Line 2 – We post the notification. The main thing to note here is the Name of “PlayBackgroundSound” and the userInfo we pass along dictToSend.

If you want to stop the background audio, use this line…

Notice this time around, we aren’t adding the userInfo parameter.

 

Check out our premium Swift and Sprite Kit Tutorial content!

Visit CartoonSmart.com