我在尝试将GameScene的 frame.width 变成自定义类时遇到了麻烦,因为我需要在我的自定义类init中定位节点的场景宽度。
HudController.swift片段
import SpriteKit
class HudController:SKNode {
var width:CGFloat
override init(){
width = GameScene().frame.width //I was hoping to add the scene width here
}
}
以下代码在我身上崩溃,我尝试了大量其他解决方案但没有成功。
有人可以帮我解决这个问题吗?
谢谢!
更新后的代码===
GameScene.swift
import SpriteKit
class GameScene: SKScene {
var hud = HudController(gameScene: self)
// set as global because I'm using it to also call hud functions in my game
}
HudController.swift
import SpriteKit
class HudController:SKNode {
var width:CGFloat
init(gameScene:SKScene){
width = gameScene.size.width
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 0 :(得分:7)
SpriteKit中的每个节点都可以使用scene
属性检索它所在的场景。
let node = SKNode()
node.scene
scene
属性返回SKScene?
,值为可选,因为如果当前节点不属于某个场景,当然也没有要检索的场景
现在,您可能想在self.scene
的初始值设定项中使用HudController
属性。
class HudController: SKNode {
var width:CGFloat
override init() {
super.init() // error: property 'self.width' not initialized at super.init call
width = self.scene!.frame.width
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
但它现在可以正常工作,因为在初始化super.init
属性之前无法调用width
。
很好,那你可以尝试一下。
class HudController: SKNode {
var width:CGFloat
override init() {
width = self.scene!.frame.width // error: use of 'self' in property access 'scene' before super.init initializes self
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
再次编译错误,因为您在调用self
之前使用super.init()
。
最后还有一个问题,当执行初始化程序时,正在创建的节点还没有父节点,因此self.scene
属性确实返回nil
。
如何解决这个问题?
首先声明初始化程序接收GameScene
。
class HudController: SKNode {
var width: CGFloat
init(gameScene:SKScene) {
width = gameScene.frame.width
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
现在,当你创建这个对象时(我希望你是从场景或已经添加到场景中的节点进行的,否则我们遇到了麻烦)你只需要编写
class Foo : SKNode {
func foo() {
guard let scene = self.scene else { return }
let controller = HudController(gameScene: scene)
}
}
另一方面,如果你从你的场景创建HudController,你只需写:
class MyScene : SKScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
let controller = HudController(gameScene: self)
}
}
就是这样。
如果你想在GameScene里面有一个HudController的实例属性,这就是代码。
class HudController: SKNode {
var width: CGFloat
init(gameScene:SKScene) {
width = gameScene.frame.width
super.init() // <-- do not forget this
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class GameScene: SKScene {
var hud : HudController?
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
hud = HudController(gameScene: self)
}
}