2017-05-24 97 views
1

我正在使用SpriteKit,並且我正在加載一個SceneKit文件,該文件包含一些使用自定義類的sprites。場景從未實際加載,因爲它到達第一個自定義類並從required init?(coder:)初始值設定項引發fatalerror。雖然自定義類實現了一個初始化器,但我無法確定爲什麼它會選擇我提供的初始化器。當我提供init()函數時,爲什麼會調用init(coder :)

自定義類:

class Bat: SKSpriteNode, GameSprite { 
    var initialSize: CGSize = CGSize(width: 44, height: 24) 
    var textureAtlas: SKTextureAtlas = SKTextureAtlas(named: "Enemies") 
    var flyAnimation = SKAction() 

    init() { 
    super.init(texture: nil, color: .clear, size: initialSize) 

    self.physicsBody = SKPhysicsBody(circleOfRadius: size.width/2) 
    self.physicsBody?.affectedByGravity = false 

    createAnimations() 
    self.run(flyAnimation) 
    } 

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

    func createAnimations() { 
    let flyFrames: [SKTexture] = [textureAtlas.textureNamed("bat"), 
            textureAtlas.textureNamed("bat-fly")] 

    let flyAction = SKAction.animate(with: flyFrames, timePerFrame: 0.12) 
    flyAnimation = SKAction.repeatForever(flyAction) 
    } 

    func onTap() {} 
} 

這裏是試圖通過孩子來加載場景,然後循環並進行初始化代碼:

遭遇經理:

class EncounterManager { 
    // Store encounter file names 
    let encounterNames: [String] = [ 
    "EncounterA" 
    ] 

    // Each encounter is a node, store an array 
    var encounters: [SKNode] = [] 

    init() { 
    // Loop through each encounter scene and create a node for the encounter 
    for encounterFileName in encounterNames { 
     let encounterNode = SKNode() 

     // Load the scene file into a SKScene instance and loop through the children 
     if let encounterScene = SKScene(fileNamed: encounterFileName) { 
     for child in encounterScene.children { 

      // Create a copy of the scene's child node to add to our encounter node 
      // Copy the position, name, and then add to the encounter 
      let copyOfNode = type(of: child).init() 
      copyOfNode.position = child.position 
      copyOfNode.name = child.name 
      encounterNode.addChild(copyOfNode) 
     } 
     } 

     // Add the populated encounter node to the array 
     encounters.append(encounterNode) 
    } 
    } 

    // This function will be called from the GameScene to add all the encounter nodes to the world node 
    func addEncountersToScene(gameScene: SKNode) { 
    var encounterPosY = 1000 

    for encounterNode in encounters { 
     // Spawn the encounters behind the action, with increasing height so they do not collide 
     encounterNode.position = CGPoint(x: -2000, y: encounterPosY) 
     gameScene.addChild(encounterNode) 

     // Double Y pos for next encounter 
     encounterPosY *= 2 
    } 
    } 
} 

我注意到使用斷點雖然它永遠不會過去加載場景。它在行if let encounterScene = SKScene(fileNamed: encounterFileName)上失敗,錯誤是來自Bat類的初始化程序中的致命錯誤。

任何幫助理解爲什麼它會選擇一個初始化器將不勝感激!

+0

謝謝馬丁! Lou在下面的答案也解釋說,我將接受那些在這裏降落的人。感謝您的快速和準確的迴應! – SamG

回答

2

你正在做的:

if let encounterScene = SKScene(fileNamed: encounterFileName) 

其中要求SKScene的init(fileNamed:)它加載一個文件,並SKScene的編碼器初始化解碼。該init會加載該文件並使用節點的編碼器init對其中的每個元素進行解碼。

如果你想從一個文件加載,你需要實現編碼器初始化。

+0

謝謝盧,我會接受這個,當它讓我。我將嘗試將其設置爲'convenience'初始值設定項,並從其中調用我的自定義init方法,並查看是否修復了它。我實際上並沒有意識到它已經存檔,然後在加載過程中將其解壓縮。 – SamG

+1

我會打電話給super來取消存檔基本屬性。 –

+0

其實你是正確的婁,它有助於當你實際加載遇到哈哈,但一切都加載到'super.init(coder:aDecoder)'調用完美的位置 – SamG

相關問題