Stephen Haney

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.

Creating our Sprite Wrapper Class

class Sprite {
    let sprite = SKSpriteNode();   // this property holds our actual SKSpriteNode
    
    init(spriteWidth:Int, spriteHeight:Int, position:CGPoint) {
        // we use an initializer function to set some properties on our SKSpriteNode
        sprite.color = UIColor.greenColor();
        sprite.size = CGSize(width: spriteWidth, height: spriteHeight);
        sprite.position = position;
    }
    
    func onTap() {
        // TODO write sprite touch event code
    }
}

That wasn’t too bad! We’ve got a reusable Sprite class that holds a SKSpriteNode. Because all Swift properties are public (at this time), we can directly edit our SKSpriteNode when we create an instance of our Sprite class using instanceOfSprite.sprite. Our onTap code isn’t doing anything yet, but we’ve created the structure for intelligent touch handling, so we can safely move on and loop back to it later.

Let’s create a more specified class called NPC. NPC will need its own game logic, but it’ll also need everything from the Sprite class. Let’s inherit from Sprite into our new NPC class:

class NPC : Sprite {
    var myMessage = String();
    
    func yell() {
        println(self.myMessage);
    }
}

Our First NPC – The Inn Keeper

We’re not doing anything fancy just yet, but we’ve already created some reusable, clean structure for our game. NPC is ready to roll, and we’ll automatically gain touch handling on NPCs when we loop back to our Sprite’s onTap function later. Let’s find out what happens when we create an instance of our NPC class right now:

// filling in some random numbers to build our innKeeper:
let innKeeper = NPC(spriteWidth: 50, spriteHeight: 80, position: CGPoint(x: 39, y: 48));
// we now have an instance of NPC called innKeeper with all the powers of NPC and Sprite
// we can edit innKeeper's SKSpriteNode directly:
innKeeper.sprite.color = UIColor.blueColor();
// and our innKeeper has any functions and properties from the NPC class as well:
innKeeper.myMessage = "All my wares, half off!";
innKeeper.yell(); // prints: All my wares, half off!

We’re not quite pushing into the app store just yet, but we’ve made good progress that will pay off shortly. We’ll definitely see the advantage to our class structure in the next post when we’ll wire up Sprite touch events. Leave a comment if this helped you get started or if you like to structure your games differently!