如何在 SpriteKit 中一次引用多个 SKNode?
How to refer to multiple SKNodes at once in SpriteKit?
为了防止出现很多相同的代码,我想通过一次调用来引用场景中的每个节点(同一父节点的所有子节点)。我在场景底部有一个门,我想检测是否有任何节点(许多不同的节点被添加到场景中)通过了这个门的 y 位置。
这是我的更新函数现在的样子:
override func update(_ currentTime: TimeInterval) {
// code I want to simplify
if Cap.position.y < illustration2.position.y
|| Cap2.position.y < illustration2.position.y
|| Cap3.position.y < illustration2.position.y
|| Cap4.position.y < illustration2.position.y
|| Cap5.position.y < illustration2.position.y
|| Cap6.position.y < illustration2.position.y
|| Cap7.position.y < illustration2.position.y
|| Cap8.position.y < illustration2.position.y
|| Cap9.position.y < illustration2.position.y
|| Cap10.position.y < illustration2.position.y {
// Transitioning to game over
let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}
}
所有的大写字母都是 illustration2 的子元素,所以我在想这样的事情:
//if the y position of any child is below the illustration2 y position the game over scene starts
if dontaiIllustration2.children.position.y < dontaiIllustration2.position.y {
}
或者另一种方法可能是检查 illustration2 节点是否具有场景中所有节点的最低 y 位置。
你不能。您需要将它们放入一个集合(数组、字典、集合等)中,然后找到一种方法来遍历它们,例如 foreach、map、compactMap(正式的 flatMap)、reduced 等。在您的情况下,我会使用减少。
let caps = [Cap1,Cap2,Cap3,Cap4,Cap5,Cap6,Cap7,Cap8,Cap9,Cap10]
let result = caps.reduce(false,{value,cap in return value || cap.position.y < illustration2.position.y})
if result {
// Transitioning to game over
let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}
这是在做什么,遍历每个节点,并用之前的结果评估当前方程。
所以我们从 false 开始,然后它会检查 cap y > illustration y。如果为真,则我们的值变为真,并且该值会延续到下一个上限。它会重复此操作,直到 运行 超出上限,然后 returns 最终值,这将是 false 或 true。
对此并不感到自豪,但您可以对父节点的子节点执行 forEach
。
let node = SKNode()
var checker = false
node.children.forEach { (node) in
if node.position.y < illustration2.position.y {
checker = true
}
}
if checker {
// Game over
}
或者如果您只想要具有特定名称的目标,您可以枚举它们:
node.enumerateChildNodes(withName: "all can have same name") { (node, stop) in
if node.position.y < illustration2.position.y {
checker = true
}
}
您也可以使用过滤器将其单行化:
node.children.filter({[=12=].position.y < illustration2.position.y}).count > 0
无论哪种方式,我都会把它放在 SKNode 的扩展中。
为了防止出现很多相同的代码,我想通过一次调用来引用场景中的每个节点(同一父节点的所有子节点)。我在场景底部有一个门,我想检测是否有任何节点(许多不同的节点被添加到场景中)通过了这个门的 y 位置。
这是我的更新函数现在的样子:
override func update(_ currentTime: TimeInterval) {
// code I want to simplify
if Cap.position.y < illustration2.position.y
|| Cap2.position.y < illustration2.position.y
|| Cap3.position.y < illustration2.position.y
|| Cap4.position.y < illustration2.position.y
|| Cap5.position.y < illustration2.position.y
|| Cap6.position.y < illustration2.position.y
|| Cap7.position.y < illustration2.position.y
|| Cap8.position.y < illustration2.position.y
|| Cap9.position.y < illustration2.position.y
|| Cap10.position.y < illustration2.position.y {
// Transitioning to game over
let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}
}
所有的大写字母都是 illustration2 的子元素,所以我在想这样的事情:
//if the y position of any child is below the illustration2 y position the game over scene starts
if dontaiIllustration2.children.position.y < dontaiIllustration2.position.y {
}
或者另一种方法可能是检查 illustration2 节点是否具有场景中所有节点的最低 y 位置。
你不能。您需要将它们放入一个集合(数组、字典、集合等)中,然后找到一种方法来遍历它们,例如 foreach、map、compactMap(正式的 flatMap)、reduced 等。在您的情况下,我会使用减少。
let caps = [Cap1,Cap2,Cap3,Cap4,Cap5,Cap6,Cap7,Cap8,Cap9,Cap10]
let result = caps.reduce(false,{value,cap in return value || cap.position.y < illustration2.position.y})
if result {
// Transitioning to game over
let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}
这是在做什么,遍历每个节点,并用之前的结果评估当前方程。
所以我们从 false 开始,然后它会检查 cap y > illustration y。如果为真,则我们的值变为真,并且该值会延续到下一个上限。它会重复此操作,直到 运行 超出上限,然后 returns 最终值,这将是 false 或 true。
对此并不感到自豪,但您可以对父节点的子节点执行 forEach
。
let node = SKNode()
var checker = false
node.children.forEach { (node) in
if node.position.y < illustration2.position.y {
checker = true
}
}
if checker {
// Game over
}
或者如果您只想要具有特定名称的目标,您可以枚举它们:
node.enumerateChildNodes(withName: "all can have same name") { (node, stop) in
if node.position.y < illustration2.position.y {
checker = true
}
}
您也可以使用过滤器将其单行化:
node.children.filter({[=12=].position.y < illustration2.position.y}).count > 0
无论哪种方式,我都会把它放在 SKNode 的扩展中。