Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How: class that inherits SKSpriteNode with init, that can call init(color:, size:)

I prototype games using shapes, and spritekit was awesome for that before swift.

Now when i try to extend a SKSpriteNode and add my init function, I can't call super.init(color, size).

I have no way to call the code that creates the shape texture.

I need to know how to either call that init function, or how to create the shape texture, so I can override the designated init, then call it using my shape texture.

EDIT: Here is the exact code I'm doing and I do almost the exact same thing in another SKSprite node extended class:

class TetrisCell : SKSpriteNode
{
    let length = 10;
    convenience init(color:UIColor) {
        var size = CGSize(width: length, height: length);

        //Not allowed to call a super's convenience init, must call non-convenience init
        super.init(color: color, size: size);
    }
}

I understand why it won't let me, so I'm looking for another way around. For now, the TetrisCell doesn't have a texture. I'd like to simply use shapes for convenience.

From what I can tell I HAVE to call super.init(texture:,color:,size:) in order to initialize my SKSpriteNode. If there is no way to do the above code, then I'd like to know what they set their SKTexture to, so I can mimic it. Something like super.init(texture: SKTexture.blankTexture) or something. Whatever they put as the texture is manipulated by the color: attribute, while my 1x1 pixel doesn't seem to be affected by the color: attribute.

like image 848
Sophie McCarrell Avatar asked Nov 14 '14 21:11

Sophie McCarrell


1 Answers

TL;DR: The texture parameter is of type SKTexture!. Since it's defined as an implicitly unwrapped optional, you can just pass nil.


First, you can't just call super(texture:, color, size:) from your convenience init, you actually have to call an init method on self. So, you'll have to add override init(texture: SKTexture!, color: SKColor!, size: CGSize) (which you can then just call super from).

Second, you can just pass nil as the texture parameter; SpriteKit will handle it appropriately.

Third (and only related because I had to make the change to get things to compile), you can't use your length property when creating your size variable because the class instance hasn't been initialized yet. Instead, I'd recommend declaring length as a var and passing it as a parameter to your convenience init.

Put all that together and you get something like this:

class TetrisCell : SKSpriteNode
{
    var length: CGFloat!

    override init(texture: SKTexture!, color: SKColor!, size: CGSize) {
        self.length = 10 // Some sort of sensible default
        super.init(texture: texture, color: color, size: size)
    }

    convenience init(color: SKColor, length: CGFloat = 10) {
        var size = CGSize(width: length, height: length);
        self.init(texture:nil, color: color, size: size)
        self.length = length
    }

    required init?(coder aDecoder: NSCoder) {
        // Decoding length here would be nice...
        super.init(coder: aDecoder)
    }
}
like image 164
Mike S Avatar answered Oct 03 '22 07:10

Mike S