当我提供init()函数时,为什么会调用init(coder :)
问题描述:
我正在使用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类的初始化程序中的致命错误。
任何帮助理解为什么它会选择一个初始化器将不胜感激!
答
你正在做的:
if let encounterScene = SKScene(fileNamed: encounterFileName)
其中要求SKScene的init(fileNamed:)
它加载一个文件,并SKScene的编码器初始化解码。该init会加载该文件并使用节点的编码器init对其中的每个元素进行解码。
如果你想从一个文件加载,你需要实现编码器初始化。
谢谢马丁! Lou在下面的答案也解释说,我将接受那些在这里降落的人。感谢您的快速和准确的回应! – SamG