循环遍历 SKNode 的所有子节点?
Posted
技术标签:
【中文标题】循环遍历 SKNode 的所有子节点?【英文标题】:Loop through all children of an SKNode? 【发布时间】:2015-01-10 20:32:51 【问题描述】:我有一个带有多个子 SKSpriteNode 的 SKNode。一个简化的例子:
var parentNode = SKNode()
var childNode1 = SKSpriteNode()
var childNode2 = SKSpriteNode()
self.addChild(parentNode)
parentNode.addChild(childNode1)
parentNode.addChild(childNode2)
我想对所有这些孩子执行colorizeWithColor
操作。当我在parentNode
上运行该操作时,没有任何效果。
我不能在父级上使用enumerateChildNodesWithName
,因为它的许多子级已经有了我正在使用的名字。
有没有办法循环遍历parentNode
的所有子级,以便对所有子级运行单个操作?
【问题讨论】:
事实证明本机 .children 调用在正常性能情况下无法使用。您必须保留自己的清单。 (好像是 2017 年。) 【参考方案1】:你可以简单地枚举parentNode.children
:
for child in parentNode.children as! [SKNode]
// ...
如有必要,检查每个孩子是否真的是SKSpriteNode
:
for child in parentNode.children
if let spriteNode = child as? SKSpriteNode
// ...
从 Swift 2 (Xcode 7) 开始, 枚举和可选类型转换可以与带有 case-pattern 的 for 循环结合使用:
for case let child as SKSpriteNode in parentNode.children
// ...
【讨论】:
【参考方案2】:截至 2017 年..
代码确实只是
for case let child as SKSpriteNode in parentNode.children
// ...
但是。
性能非常糟糕:无法使用。
您必须保留自己的列表。
当然,如果您要创建许多“坦克”或“宇宙飞船”,您自然会将它们保存在一个列表中。如果您需要迭代,这是唯一可行的方法。
我运行了一些这样的测试代码...
// try Apple's native .children call...
for case let s as SomeSpriteClass in children k += 1
let t1 = a.microseconds()
// simply use your own list...
let b = Date()
for s in spaceships k += 1
let t2 = b.microseconds()
print("\(t1) \(t2)")
如果您只是遍历自己的列表,速度会快 3 到 4 倍。
iPad 上的典型输出 ...
939 43
140 33
127 33
117 37
109 30
126 33
127 33
109 29
96 30
96 29
99 30
97 30
97 30
(特别是,正如您所料,内置枚举永远需要“第一次”时间。)
鉴于性能,实际上您必须保留自己的精灵列表并使用该列表。
【讨论】:
【参考方案3】:您可以通过访问父级的children
-attribute 来获取子级数组,然后循环遍历它们并在它们上运行colorizeWithColor
。
let children = parentNode.children
for child in children
// Do something.
【讨论】:
【参考方案4】:我需要遍历 SCNNode
以查找我创建的自定义 SCNNode
子类。尽管这个问题是针对 SKNNode @MartinR's 的答案,但我能找到的唯一答案是让我朝着正确的方向前进。我不得不对其进行调整,但这是我使用的:
for child in parentNode.childNodes
if let myCustomNode = child as? MyCustomNode
// ...
【讨论】:
以上是关于循环遍历 SKNode 的所有子节点?的主要内容,如果未能解决你的问题,请参考以下文章