如何在 SpriteKit 中一次引用多个 SKNode?

Posted

技术标签:

【中文标题】如何在 SpriteKit 中一次引用多个 SKNode?【英文标题】:How to refer to multiple SKNodes at once in SpriteKit? 【发布时间】:2018-06-13 11:21:51 【问题描述】:

为了防止出现大量相同的代码,我想通过一次调用来引用场景中的每个节点(同一父节点的所有子节点)。我在场景底部有一个门,我想检测是否有任何节点(添加到场景中的许多不同节点)通过了这个门的 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 

        

或者另一种方法是检查插图 2 节点是否具有场景中所有节点中最低的 y 位置。

【问题讨论】:

给他们一组userData(字典),放在同一个组里。 【参考方案1】:

你不能。您需要将它们放入一个集合(数组、字典、集合等)中,然后找到一种方法来遍历它们,例如 foreach、map、compactMap(正式为 flatMap)、reduce 等。在您的情况下,我会使用减少。

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。如果为真,那么我们的值将变为真,并且该值会延续到下一个上限。它会重复此操作,直到您用完大写字母,然后返回最终值,该值将是 false 或 true。

【讨论】:

结果后写什么? @KnightOfDragon【参考方案2】:

对此并不感到自豪,但您可以在父节点的子节点上执行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($0.position.y < illustration2.position.y).count > 0

无论哪种方式,我都会把它放在 SKNode 的扩展中。

【讨论】:

在更新函数中实现代码之前是否需要添加任何东西? @Vollan 永远不要为你的代码感到羞耻,尽你所能写出最好的东西,并在别人提供更好的东西时向他们学习。你的回答绝对没有问题,它确实解决了问题。 @Jay23 checkerSKNode 应该在类级别而不是在更新函数中,否则一切正常 谢谢@Knight0fDragon 我更喜欢它不是一个好看的方式来拥有这样的布尔......也许像node.children.filter($0.position.y &lt; illustration2.position.y).count &gt; 0会更好。

以上是关于如何在 SpriteKit 中一次引用多个 SKNode?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift SpriteKit 在 For 循环中一一创建 SKSprite 节点

如何在 Firestore 中一次创建/更新多个文档

如何在 Eclipse 中一次显示 100 多个任务 //TODO?

如何在 C# 中一次播放多个声音

如何在mysql中一次更改多个表?

如何在 Prometheus 中一次调用执行多个查询