Joyful Games – iPhone game development with Apple’s Swift new language

Email Contact

Play SnakeJoy! The most addicting fun snake game on the internet

Play SnakeJoy in Your Browser!

How to Add Interstitial iAds in SpriteKit with Swift

I recently implemented interstitial iAds for the first time in Swift. I want to share my implementation of interstitial iAds, since I found the current google-sphere a bit lacking (at least in Swift). You’ll need to do some initial work in iTunes Connect to get your iOS app ready for iAds. Once you are ready, you can base your iAds integration on my example.

Implement interstitial iAds into your SpriteKit game

A test interstitial iAd successfully displayed in the iOS emulator

I chose to create a new SKScene to serve as a transition between my menu and game scenes. This transition scene displays the iAd interstitial and uses this time to preload and cache my game textures (the first time through the scene). I attach the iAd interstitial as a sub view on this transition scene’s parent view. We’ll also create our own UIButton to close the interstitial ad, as I show below.

First, import iAd into your file:

import iAd

Second, adhere to the ADInterstitialAdDelegate protocol in your class definition. This allows us to get callbacks after the interstitial iAds close.

class TransitionScene : SKScene, ADInterstitialAdDelegate {

Third, create these properties on the TransitionScene class:

    var interAd:ADInterstitialAd?
    var interAdView = UIView()
    var closeButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton

Fourth, configure the close button in the TransitionScene didMoveToView function:

override func didMoveToView(view: SKView) {
    // Define a close button size:
    closeButton.frame = CGRectMake(20, 20, 70, 44)
    closeButton.layer.cornerRadius = 10
    // Give the close button some coloring layout:
    closeButton.backgroundColor = UIColor.whiteColor()
    closeButton.layer.borderColor = UIColor.blackColor().CGColor
    closeButton.layer.borderWidth = 1
    closeButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
    // Wire up the closeAd function when the user taps the button
    closeButton.addTarget(self, action: "closeAd:", forControlEvents: UIControlEvents.TouchDown)
    // Some funkiness to get the title to display correctly every time:
    closeButton.enabled = false
    closeButton.setTitle("skip", forState: UIControlState.Normal)
    closeButton.enabled = true
    closeButton.setNeedsLayout()
}

Fifth, implement these functions in your TransitionScene class:

// iAd
func prepareAd() {
    println(" --- AD: Try Load ---")
    // Attempt to load a new ad:
    interAd = ADInterstitialAd()
    interAd?.delegate = self
}

// You can call this function from an external source when you actually want to display an ad:
func showAd() -> Bool {
    if interAd != nil && interAd!.loaded {
        interAdView = UIView()
        interAdView.frame = self.view!.bounds
        self.view?.addSubview(interAdView)
        
        interAd!.presentInView(interAdView)
        UIViewController.prepareInterstitialAds()
        
        interAdView.addSubview(closeButton)
    }
    
    // Return true if we're showing an ad, false if an ad can't be displayed:
    return interAd?.loaded ?? false
}

// When the user clicks the close button, route to the adFinished function:
func closeAd(sender: UIButton) {
    adFinished()
}

// A function of common functionality to run when the user returns to your app:
func adFinished() {
    closeButton.removeFromSuperview()
    interAdView.removeFromSuperview()
    // (Do whatever is next in your app)
}

// The ad loaded successfully (we don't need to do anything for the basic implementation)
func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
    println(" --- AD: Load Success ---")
}

// The ad unloaded (we don't need to do anything for the basic implementation)
func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) {
    println(" --- AD: Unload --- ")
}

// This is called if the user clicks into the interstitial, and then finishes interacting with the ad
// We'll call our adFinished function since we're returning to our app:
func interstitialAdActionDidFinish(interstitialAd: ADInterstitialAd!) {
    println(" --- ADD: Action Finished --- ")
    adFinished()
}

func interstitialAdActionShouldBegin(interstitialAd: ADInterstitialAd!, willLeaveApplication willLeave: Bool) -> Bool {
    return true
}

// Error in the ad load, print out the error
func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) {
    println(" --- AD: Error --- ")
    println(error.localizedDescription)
}

Sixth, call your new prepareAd function to load a new ad. I’ll often create an instance of the TransitionScene in a separate scene (like my GameScene) so I can load ads before I need to show them (for instance: as soon as the player dies, but before they click new game).

Create an instance of your TransitionScene in the GameScene (or wherever you need it) and then call prepareAd a few moments before you’ll need the transition:

transitionScene.prepareAd()

Finally, in your GameScene (or wherever you are) present the transitionScene instance:

self.view?.presentScene(transitionScene, transition: .crossFadeWithDuration(0.6))

You can call your new showAd function from within the TransitionScene whenever you want the interstitial iAd to show. If you want it to show as soon as the transition scene starts, add the following code to your TransitionScene didMoveToView function:

// Try to show an ad
let adShown = showAd()

// If no ad, just move on
if adShown == false {
    // Do whatever's next for your app
}

I hope that helps you implement interstitial iAds into your SpriteKit Swift app. Leave me a comment if you need any help putting this to use. Cheers!

SKSpriteNodes anchorPoint in Swift and SpriteKit

Note: This is a free excerpt from my new book, Game Development with Swift. If you like this post, you’ll love the book! The book walks you through the creation of a 2D iOS game from start to publication on the App Store. So far, I’ve received nothing but great feedback from readers. Check out my new Swift SpriteKit book on Amazon

SpriteKit uses a grid of points to position nodes. In this grid, the bottom left corner of the scene is (0,0), with a positive X-axis to the right and a positive Y-axis to the top. Similarly, on the individual sprite level, (0,0) refers to the bottom left corner of the sprite, while (1,1) refers to the top right corner.

Alignment with Anchor Points

Each sprite has an anchor point property, or an origin. The anchorPoint property allows you to choose which part of the sprite aligns to the sprite’s overall position.

The default anchor point is (0.5,0.5), so new SKSpriteNodes center perfectly on their position.
(more…)

Upside Down SKPhysicsBody when Loaded From Texture

I ran into an odd SpriteKit bug the other day when preloading and caching my texture atlases. It seems that you cannot create more than one SKPhysicsBody from a single instance of a texture, or all subsequent physics bodies will be created upside down. This StackOverflow thread suggests it’s an issue with internally cached textures.

Building an SKPhysicsBody from a cached texture creates inverted physics bodies

Building an SKPhysicsBody from a cached texture creates inverted physics bodies

(more…)

Saving SpriteKit Game Data in Swift – It’s Easy with NSCoder

Saving SpriteKit game information on iOS is a common requirement. We need to save the player’s progress, preferences, and high scores. I recently implemented a high score system for Krate. Though this Swift code is tailored for score keeping, it can be easily adapted to persist save game data or any other information you need to save between games.

We’ll inherit NSCoder to serialize our objects, then store the data using one of several iOS data persistence methods. I chose to save my high score data using plist files, saved inside my game’s directory. (You can also use NSUserDefaults to store serialized objects, though it is intended only for user preferences. Another option is Core Data, which is robust and useful for complicated Swift persistence tasks.)

First off, we’ll need a serializable class that will store our save game data. NSCoding allows us to translate our class into data that can be saved to the file system.

// inherit from NSCoding to make instances serializable
class HighScore: NSObject, NSCoding {
    let score:Int;
    let dateOfScore:NSDate;
    
    init(score:Int, dateOfScore:NSDate) {
        self.score = score;
        self.dateOfScore = dateOfScore;
    }
    
    required init(coder: NSCoder) {
        self.score = coder.decodeObjectForKey("score")! as Int;
        self.dateOfScore = coder.decodeObjectForKey("dateOfScore")! as NSDate;
        super.init()
    }
    
    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(self.score, forKey: "score")
        coder.encodeObject(self.dateOfScore, forKey: "dateOfScore")
    }
}

Great! Next, we want to create a manager class to store an array of HighScores, and perform the save action. Mind the comments – the code required to save and read plist files is long:

class HighScoreManager {
    var scores:Array<HighScore> = [];
    
    init() {
        // load existing high scores or set up an empty array
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let documentsDirectory = paths[0] as String
        let path = documentsDirectory.stringByAppendingPathComponent("HighScores.plist")
        let fileManager = NSFileManager.defaultManager()
        
        // check if file exists
        if !fileManager.fileExistsAtPath(path) {
            // create an empty file if it doesn't exist
            if let bundle = NSBundle.mainBundle().pathForResource("DefaultFile", ofType: "plist") {
                fileManager.copyItemAtPath(bundle, toPath: path, error:nil)
            }
        }
        
        if let rawData = NSData(contentsOfFile: path) {
            // do we get serialized data back from the attempted path?
            // if so, unarchive it into an AnyObject, and then convert to an array of HighScores, if possible
            var scoreArray: AnyObject? = NSKeyedUnarchiver.unarchiveObjectWithData(rawData);
            self.scores = scoreArray as? [HighScore] ?? [];
        }
    }
    
    func save() {
        // find the save directory our app has permission to use, and save the serialized version of self.scores - the HighScores array.
        let saveData = NSKeyedArchiver.archivedDataWithRootObject(self.scores);
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray;
        let documentsDirectory = paths.objectAtIndex(0) as NSString;
        let path = documentsDirectory.stringByAppendingPathComponent("HighScores.plist");
        
        saveData.writeToFile(path, atomically: true);
    }
    
    // a simple function to add a new high score, to be called from your game logic
    // note that this doesn't sort or filter the scores in any way
    func addNewScore(newScore:Int) {
        let newHighScore = HighScore(score: newScore, dateOfScore: NSDate());
        self.scores.append(newHighScore);
        self.save();
    }
}

We can persist any type of game data we need with this same pattern . . . and though the code to write and read plist files is a bit verbose, the concept is actually quite straightforward. Kindly leave a comment with any questions or suggestions.

A quick note of credit: thanks to this blog post for solid plist persistence info.

Camera Shake with SpriteKit in Swift

Previously, we’ve covered using a master SKSpriteNode called ‘world’ to gather all of our game sprites on one parent sprite node. This allows us to move the entire ‘camera’ of our game by simply moving around this one sprite node. Now let’s apply a solid camera shake on important game events.
(more…)

Keep Game Sprites Organized by
Extending SKSpriteNode with a Wrapper Class

Xcode Project and Game Organization

Even a simple game can quickly explode into a rats nest if we don’t adhere to structure from the start. I’ve learned that it’s very helpful to create a Sprite class that wraps SKSpriteNode. You can extend this class with custom functions (I’ll detail creating a ‘touch’ event handler for sprites next post), and inherit down into other classes that share basic Sprite functions like enemies, the player class, and NPCs.
(more…)

Using the Power of Swift Enums

Quickly: General Enum Usage

You can use enums to create a new type in your code for use with related values. It can be a shortcut for a Class when you know the number of instances you’ll need ahead of time (you can create an enum called ‘Month’ with members like January, February, March, and so on). Typically you’d use an enum when all values can be hard coded, but Swift opens the door for some other uses. Let’s explore the new abilities.
(more…)

Positioning SKSprites in SpriteKit with
SKScene scaleMode

I quickly ran into a snag upon firing up a new Xcode SpriteKit project and attaching a few test SKSpriteNodes to my SKScene. None of my dummy sprites were showing up at the size or location I anticipated! After a bit of web searching I realized that SKScenes are automatically scaled based on the screen size of the device. I can see how this is pretty handy, but it’s the kind of thing I like to make sure I get right early in the dev process. Here’s how I created a consistent positioning and sizing system I can trust.
(more…)

Swift, Objective-C and Barriers to Entry
(or “My First iPhone Game”)

I want to build a fun iPhone app. I always have . . . just a small something to show off to my coder friends. I want to spend time daydreaming about becoming featured, going viral, and turning a hobby into an income stream.  Or, it can simply exist as an enjoyable exercise in creation and learning.  But here’s the holdup: I’ve always seemed to have better options than spending my time learning Obj-C’s syntax and, some would say, archaic quirks.  As an outsider, it’s too high a barrier to entry for a side project.  So, I immediately took to the idea of a new language when Apple announced Swift last Monday at WWDC.

Swift – Why I’m Optimistic

Swift’s syntax is very familiar and friendly to web developers or anyone versed in C based languages.  I’m 28 and I’ve been working on the web for the past 11 years; I spend a lot of my time with JavaScript and C#, and to a lesser extent Python and PHP.  Anyone with some basic knowledge of those languages can blow through the Swift book in a few days and feel confident opening Xcode and creating a new project.
(more…)