我在尝试将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
}
}
Run Code Online (Sandbox Code Playgroud)
下面的代码崩溃了,我尝试了其他大量的解决方案但没有成功.
有人可以帮我解决这个问题吗?
谢谢!
更新的代码===
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
}
Run Code Online (Sandbox Code Playgroud)
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")
}
}
Run Code Online (Sandbox Code Playgroud)
SpriteKit中的每个节点都可以使用scene属性检索它所在的场景.
let node = SKNode()
node.scene
Run Code Online (Sandbox Code Playgroud)
该scene属性返回a 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")
}
}
Run Code Online (Sandbox Code Playgroud)
但它现在可以工作,因为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")
}
}
Run Code Online (Sandbox Code Playgroud)
再次编译错误,因为您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")
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当你创建这个对象时(我希望你是从场景或已经添加到场景中的节点进行的,否则我们遇到了麻烦)你只需要写
class Foo : SKNode {
func foo() {
guard let scene = self.scene else { return }
let controller = HudController(gameScene: scene)
}
}
Run Code Online (Sandbox Code Playgroud)
另一方面,如果你从你的场景创建HudController你只需写:
class MyScene : SKScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
let controller = HudController(gameScene: self)
}
}
Run Code Online (Sandbox Code Playgroud)
而已.
如果你想在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)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1233 次 |
| 最近记录: |