Con*_*sed 6 initialization subclass sprite-kit skspritenode swift
我想创建一个比SpriteNode的touchesBe更高级别的SKShapeNode,所以当我想从这个sprite上的touchesBegun事件将SKShapeNode添加到屏幕时,形状已经存在,我只是从内部将它添加到屏幕touchesBegan覆盖.
TL; DR,在我的SKSpriteNode中,我正在尝试预先构建SKShapeNode,当触摸Sprite时,该SKShapeNode将用作动画环.
我想用变量/常量创建SKShapeNode,这样我就可以轻松编辑它的值了......
因此,在子类的根目录中,我有颜色,大小和线宽的变量,可以在创建SKShapeNode时使用...
class Balls: SKSpriteNode {
var ringSize: CGFloat = 64
var ringColor: SKColor = SKColor.white
var ringWidth: CGFloat = 16
....
Run Code Online (Sandbox Code Playgroud)
再往下,但仍然是班级的根,我创建我的戒指:
let ring = SKShapeNode(circleOfRadius: ringSize)
Run Code Online (Sandbox Code Playgroud)
我立即受到了深情的怀疑:
无法在属性初始化程序中使用实例成员'ringSize',属性初始化程序在'self'可用之前运行.
精细.好.我知道了.您希望在将值分配给self之前,应该在创建属性时对类进行函数调用.无论是在这里还是在那里,我认为我变得狡猾,并且可以通过将所有内容包装在函数中来解决这个问题:
class Balls: SKSpriteNode {
var ringSize: CGFloat = 64
var ringColor: SKColor = SKColor.white
var ringWidth: CGFloat = 16
var myRing = SKShapeNode()
func createRing() -> SKShapeNode{
let ring = SKShapeNode(circleOfRadius: ringSize)
ring.strokeColor = ringColor
ring.lineWidth = ringWidth
return ring
}
Run Code Online (Sandbox Code Playgroud)
这不会产生任何错误,我的兴奋也会增加.
所以我添加另一行,创建实际的戒指:....
myRing = createRing()
Run Code Online (Sandbox Code Playgroud)
又死了:
!预期的声明
我完全不知道这意味着什么,并开始随机尝试奇怪的事情.
其中一个正在进入我已经凌乱的便利初始化程序并添加myRing = createRing()到那里...... 这个工作!
这是如何以及为什么这样做,这是绕道初始化的最好/正确/正确的方法吗?
这是我的奇怪和误解的初始化者的完整课程.
import SpriteKit
class Circle: SKSpriteNode {
var ringSize: CGFloat = 96
var ringColor: SKColor = SKColor.white
var ringWidth: CGFloat = 8
var myRing = SKShapeNode()
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
super.init(texture: texture, color: color, size: size)
}
convenience init() {
self.init(color: SKColor.clear, size: CGSize(width: 100, height: 100))
myRing = createRing()
addChild(myRing)
print("I'm on the screen")
explodeGroup = create_explosionActionGroup()
}
convenience init(color: UIColor, size: CGSize, position: CGPoint) {
self.init(color: color, size: size)
self.position = position
myRing = createRing()
explodeGroup = create_explosionActionGroup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func createRing() -> SKShapeNode{
let ring = SKShapeNode(circleOfRadius: ringSize)
ring.strokeColor = ringColor
ring.lineWidth = ringWidth
return ring
}
Run Code Online (Sandbox Code Playgroud)
\n\n\n我立即受到了亲切而神秘的欢迎:
\n\n\n\n无法在属性初始值设定项内使用实例成员“ringSize”,属性初始值设定项在“self”可用之前运行。
\n
因此,解决此问题的一种方法是通过ringSize另一种方式提供默认值,例如
static let defaultRingSize: CGFloat = 64\n\nvar ringSize: CGFloat = Circle.defaultRingSize\nlet ring = SKShapeNode(circleOfRadius: Circle.defaultRingSize)\nRun Code Online (Sandbox Code Playgroud)\n\n...但我质疑为什么你有var ringSize这样的财产。难道你不应该didSet在它上面有一个观察者,这样如果你改变它的值,你就可以更新 的形状吗ring?
\n\n\n又死了:
\n\n\n\n!预期声明
\n
在你的问题中,你不清楚你实际上是如何触发这个的,但我猜你尝试过这样的事情:
\n\nclass Circle: SKSpriteNode {\n\n var ringSize: CGFloat = 96\n\n var myRing = SKShapeNode()\n myRing = createRing() // \xe2\x80\x9cExpected declaration\xe2\x80\x9d\xc2\xa0error on this line\nRun Code Online (Sandbox Code Playgroud)\n\n这里的问题是,您已在类的主体中放置了一条语句,但主体中只允许使用声明。
\n\n\n\n\n其中之一是进入我已经很混乱的便利初始化程序并在其中添加 myRing = createRing() ......并且这有效!
\n\n这是如何以及为什么起作用的
\n
类自己的所有实例变量都必须在调用之前初始化super.init。由于myRing有默认值,编译器会在指定的初始值设定项中有效地插入myRing调用之前的初始化super.init,如下所示:
override init(texture: SKTexture?, color: UIColor, size: CGSize) {\n // Compiler-inserted initialization of myRing to the default\n // value you specified:\n myRing = SKShapeNode()\n\n super.init(texture: texture, color: color, size: size)\n}\nRun Code Online (Sandbox Code Playgroud)\n\n既然您声明了var myRing,您可以稍后将其更改为SKShapeNode您真正想要的定制。
\n\n\n这是循环初始化的最佳/正确/正确方法吗?
\n
好吧,\xe2\x80\x9c绕排水管\xe2\x80\x9d意味着\xe2\x80\x9c失败\xe2\x80\x9d,所以我猜你在问这是否是\xe2\x80\x9c最好/正确的/proper way\xe2\x80\x9d\xc2\xa0to 在初始化时失败\xe2\x80\xa6 我认为这不是失败的最佳方式,因为你最终并没有真正失败。
\n\n或者也许你的意思是 \xe2\x80\x9c 我讨厌 Swift 初始化的方式,所以我要抛出一些阴影 \xe2\x80\x9d,在这种情况下,你什么也看不到。
\n\n但也许你真的意味着 \xe2\x80\x9cis 这是初始化我的实例\xe2\x80\x9d 的最佳/正确/正确的方法,在这种情况下,\xe2\x80\x9cbest\xe2\x80\x9d 和 \ xe2\x80\x9cright\xe2\x80\x9d 和 \xe2\x80\x9cproper\xe2\x80\x9d 非常主观。
\n\n但我可以客观地指出,您正在创建一个SKShapeNode(作为 的默认值myRing)只是为了立即丢弃它并创建另一个SKShapeNode. 所以这是一种浪费。您还可以在两个便利初始化程序中调用它们createRing,但您可以将它们分解到指定的初始化程序中。
但我什至不会那样做。SKShapeNode\ 的path属性是可设置的,因此您只需创建一个默认值SKShapeNode,然后path在调用super.init. 这也使得处理对属性ringSize和其他属性的更改变得更加容易,因为您可以通过知道如何匹配myRing属性的单个方法来汇集所有更改。
我可能会这样写你的课程:
\n\nimport SpriteKit\n\nclass Circle: SKSpriteNode {\n\n var ringSize: CGFloat = 96 {\n // Use an observer to update myRing if this changes.\n didSet { configureMyRing() }\n }\n\n var ringColor = SKColor.white {\n didSet { configureMyRing() }\n }\n\n var ringWidth: CGFloat = 8 {\n didSet { configureMyRing() }\n }\n\n // This can be a let instead of a var because I\'m never going to\n // set it to a different object. Note that I\'m not bothering to\n // initialize myRing\'s path or any other property here, because\n // I can just call configureMyRing in my init (after the call to\n // super.init).\n let myRing = SKShapeNode()\n\n override init(texture: SKTexture?, color: SKColor, size: CGSize) {\n super.init(texture: texture, color: color, size: size)\n\n // Call this now to set up myRing\'s path and other properties.\n configureMyRing()\n }\n\n convenience init() {\n self.init(color: SKColor.clear, size: CGSize(width: 100, height: 100))\n\n // No need to do anything to myRing now, because my designated\n // initializer set it up completely.\n\n addChild(myRing)\n print("I\'m on the screen")\n\n // Commented out because you didn\'t provide this property\n // or method in your question.\n// explodeGroup = create_explosionActionGroup()\n }\n\n convenience init(color: SKColor, size: CGSize, position: CGPoint) {\n self.init(color: color, size: size)\n self.position = position\n\n // Commented out because you didn\'t provide this property\n // or method in your question.\n// explodeGroup = create_explosionActionGroup()\n }\n\n required init?(coder aDecoder: NSCoder) {\n fatalError("init(coder:) has not been implemented")\n }\n\n private func configureMyRing() {\n myRing.path = CGPath(ellipseIn: CGRect(x: -ringSize / 2, y: -ringSize / 2, width: ringSize, height: ringSize), transform: nil)\n myRing.strokeColor = ringColor\n myRing.lineWidth = ringWidth\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |