SKSpriteNodeのinitializerでちょっとつまづいた

久しぶりにFrappybirdを作りたいなと思ったのでコツコツ作り始めたのですが、Birdの設定などを保持したBirdSpriteクラスを作成しようとした時にinitializeが成功せずつまづきました。

コードはこんな感じで作ろうとしてました。

class BirdSprite: SKSpriteNode {
    
    init(name: String){
        super.init(fileNamed: name)!
    }

    required init?(coder aDecoder: NSCoder) {
        //NOP
        fatalError("init(coder:) has not been implemented")
    }
}

エラー

Must call a designated initializer of the superclass 'SKSpriteNode'

解決策

スーパークラスのinitializer呼んでるのになんでだろうと調べてみると、いつも使う画像のファイル名をStringで渡すイニシャライザはconvenienceというアノテーションがついていました。

convenience init は中で本物のinitを呼ばないといけないようでした。SKSpriteNodeの持っている本物のinitは以下の1つだけのようです

public init(texture: SKTexture?, color: UIColor, size: CGSize)

こけていたコードを以下のように修正したら直りました🤖

class BirdSprite: SKSpriteNode {
    
    init(name: String){
        let texture = SKTexture(imageNamed: name)
        super.init(texture: texture], color: .clear, size: texture.size())
    }

    required init?(coder aDecoder: NSCoder) {
        //NOP
        fatalError("init(coder:) has not been implemented")
    }
}

参考文献

Swift – Must call a designated initializer of the superclass SKSpriteNode error

[Swift] convenienceイニシャライザとdesignated(指定)イニシャライザ