我正在关注SpriteKit简介的教程,我收到了这个错误,在教程中,就像这样,但教程是在几个月前发布的,所以有些语法可能有改变。
错误出现在如果helloNode!= nil {...}
任何帮助?
谢谢!
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
var helloNode:SKNode = childNodeWithName("helloNode")!
//I get the error in the next line
if helloNode != nil {
helloNode.name = nil
var moveUp:SKAction = SKAction.moveByX(0, y: 100, duration: 0.5)
var zoom:SKAction = SKAction.scaleTo(2, duration: 0.25)
var pause:SKAction = SKAction.waitForDuration(0.5)
var fadeAway = SKAction.fadeOutWithDuration(0.25)
var remove = SKAction.removeFromParent()
var moveSequence = SKAction.sequence([moveUp, zoom, pause, fadeAway, remove])
helloNode.runAction(moveSequence)
}
}
答案 0 :(得分:2)
在这一行:
var helloNode:SKNode = childNodeWithName("helloNode")!
childNodeWithName
的返回值(可选)应用于强制解包运算符,其中:
SKNode
除此之外,helloNode
被声明为非可选SKNode
,非可选项永远不会为零。
要修复编译错误,请执行以下更改:
var helloNode: SKNode? = childNodeWithName("helloNode")
if let helloNode = helloNode {
...
}
通过这些更改,helloNode
是可选的SKNode
,可以包含nil或SKNode
的实例。在下一个中使用了可选绑定:如果helloNode
为nil,则let helloNode = helloNode
计算结果为false,并跳过if
语句中的代码。另一方面,如果helloNode
不是nil,则它包含的值将被解包并分配给非可选变量(具有相同的名称,但您可以选择任何您想要的名称),其范围仅限于代码if
语句的块。
答案 1 :(得分:1)
!
末尾的childNodeWithName("helloNode")!
表示该值不能为零,因此零检查无效。试试这个:
if let temp = helloNode {
// use temp instead of helloNode
...
}
或者将您的变量声明行更改为:
var helloNode:SKNode? = childNodeWithName("helloNode")
您可以在此处详细了解如何使用Optionals:Optionals in Swift
答案 2 :(得分:0)
这里已经有了不错的答案,但是它们(以及原始问题)涉及的代码并不像它可能的简洁或清晰。
childNodeWithName
的返回类型已经是可选的(SKNode?
),因此在分配给您的本地helloNode
变量时无需明确声明它。同样,类型推断使您无需为您正在创建的所有SKAction
声明类型。
使用if let
并使用与封闭范围相同的名称遮蔽本地绑定的非可选项并不是最可读的代码。
此外,如果您只分配给helloNode
一次,并且仅在检查该分配后使用它,则只需将其绑定在一个范围内。说到只分配一次名称,就没有必要使用var
来换取不会发生变化的事情。
SKAction
是可重复使用的。如果这种情况在游戏过程中不止一次发生,您可以考虑创建moveSequence
一次(懒得偶然)并将其存放在一个属性中。
所以,改进版本:
lazy var moveSequence: SKAction = {
let moveUp = SKAction.moveByX(0, y: 100, duration: 0.5)
let zoom = SKAction.scaleTo(2, duration: 0.25)
let pause = SKAction.waitForDuration(0.5)
let fadeAway = SKAction.fadeOutWithDuration(0.25)
let remove = SKAction.removeFromParent()
return SKAction.sequence([moveUp, zoom, pause, fadeAway, remove])
}()
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let helloNode == childNodeWithName("helloNode") {
helloNode.name = nil
helloNode.runAction(moveSequence)
}
}