Thinking Swiftly

iPhone game development with Apple’s Swift new language

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…)

Game Development with Swift Released!

Late last night I received an email from my publisher: Game Development with Swift is officially published! It is so exciting to have my work out in the world, helping people learn a fun skill. I can’t wait for feedback and to see some of the games the readers create. If you are interested in SpriteKit, Swift, or any 2D game development on iPhone, iPad, and iOS in general, check it out!

Read the Amazon Game Development with Swift page

. . . or the Publisher Game Development with Swift page

Event Triggers and Event Listeners in Swift, Updated Swift 6.2

I recently updated my mini-library that adds Backbone.js style listeners and triggers to Swift. I improved the ability to pass information between triggers and listeners, and updated the syntax for Swift 6.2, using Xcode 6.3 beta 2. Using custom events is a pretty nifty way of organizing your Swift project.

Download

Download it here: Swift Custom Events on GitHub

Example

Here’s an example of how Swift Custom Events works:

Let’s create a cat class that can bug us while we’re coding:

class Cat {
    let events = EventManager();

    func meow() {
        println("Cat: MRaawwweeee");
        self.events.trigger("meow", information: "The cat is hungry!");
    }
}

(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.

Raise the Skill Cap by Hinting at Upcoming Events

krate iphone game colors hud update

The HUD now displays the next 3 colors for the player.

One of my concerns with Krate is that I would end up with a game that came down to luck more than skill. One of my goals is to make the game re-playable because there’s potential for growth. I want a high “skill cap”, such that a talented player will end up with a dramatically better result than a casual player. One example of a low skill cap was the Paladin class in early WoW. They were very beginner friendly, with only a few buttons to press. The downside was that an experienced player couldn’t perform much better than a beginner. DOTA2 is another game with a mix of low skill cap (drow ranger) and high skill cap (meepo) heroes. With each decision I make, I try to think “will this raise or lower the skill cap?” because I believe a high skill cap gives an authentic reason for the player to replay the game.

Strategy through Information

I want the player to be actively planning and strategizing while playing Krate. Players have a chance to plan and react well or poorly to each game event. Players can better plan if I make sure to give plenty of information. One way I found to do this is to show the upcoming colors that the player will place. Originally, I was only showing the active color to be placed, and I found I wasn’t planning much, but simply reacting to each new color assignment. I built out a system to display the next 3 colors and I think it’s added a lot to the game’s strategy. Check out the video with the new color assignment HUD:

(more…)

Swift Events: Create Triggers and Listeners in Swift

Backbone includes an elegant and awesome events system that allows for some beautiful code organization in web apps. The events system lets you put your code where it belongs, rather than being tied in to a bunch of function calls in the event trigger. You can add and remove functionality from different events as well. It’s especially useful for game systems like keeping track of events that count towards achievements.

I wanted this functionality for Krate, my iPhone puzzle game, so I wrote a fast solution that mimics the most usable parts of Backbone’s system for custom Swift events triggering.

You can find it here: Swift Events on GitHub. There’s some examples and more information on using the class. Give it a try and let me know how you like it – it’s very usable right now, but I’m definitely open to feedback and improvements.

Krate Advancing by Leaps and Bounds

iPhone puzzle game krate beta graphics

Adding placeholder graphics to Krate makes it feel way more fun!

I am joining in the Summer of Swift fun with Krate. It’s a fitting event for me, as the timeframe fits my predetermined goals perfectly. Plus it enforces a regular update schedule which I can incorporate into Thinking Swiftly.

Krate has improved tremendously over the past few days. The game is already coming to life through new graphics and some easy juice like screen shakes. I’m using the excellent Kenney Asset Pack. Kenney is free to use, but I strongly recommend making a donation as it provides terrific placeholder art.

Quick Progress

I created a lot of the underlying systems for the game this week, including a Sound manager, an open source custom events manager for Swift, and the structure for keeping score and adjusting difficulty.

Also new is the creeping plague of darkness that gives the game a quick pace, and some placeholder particle effects to suggest tile placements. Phew! Lots of good stuff. I’ve included a video of an entire game in the full post.

(more…)

The New iPhone Puzzle Game: Introducing Krate

iphone puzzle game chess board

First, I wanted to build the game board using SKSpriteNodes. A good launching point for writing some game rules!

My favorite part of making games . . .

My favorite part of making games is looking back on early screenshots. I love to watch those early, blocky chunks of color transform into immersive game elements. In that spirit, I want to post some early screenshots of Krate, my new twisty, fun iPhone puzzle game.

Krate is my summer Swift learning project, born through the fortuitous coincidence of the Swift announcement with the Spring semester’s end. I often start overly ambitious game projects, doomed to drown by their own weight. No more! This time, I’m going to make an iPhone puzzle game. How hard can it be? 😉

Krate’s concept is simple; anyone who’s played any of the gem/jewel games can pick it up. That said, I wouldn’t be satisfied with a pure copy, so I spent some time thinking on unique mechanics. In this puzzle game, you start with a blank board and fill in tiles with a color randomly assigned on each turn. You can clear tiles any time you have 3 or more of the same color touching. That’s just the beginning, I’ve added more mechanics and compiled an early gameplay video.
(more…)