SpriteKit:将节点插入链中

时间:2018-07-12 16:06:04

标签: swift sprite-kit skaction

macOS 10.13,Xcode 10b3

我有一个SpriteKit应用程序,其中SKSpriteNodes排成一行(它们包含在数组中),我想在该行/数组中插入新元素,并沿同一行移开先前的节点。 (想想Zuma的复仇,一连串的节点移动,您可以射击以将新的节点插入到该链中。)

我尝试了以下方法:

  • 使用物理学和SKConstraint确保我的节点仅移动正确的量。在当前系统下,此操作会失败,因为物理实体有时会从其节点分离(它们会在鼠标按下时插入力矢量,并且会根据物理实体计算碰撞)。随后出现了希金克斯。 detached physics bodies
  • 使用atPoint递归检查目标位置中是否有一个节点。直到您生成新节点的速度快于旧节点的移动速度(此时整个链崩溃)为止,这种方法都可以正常工作。我不想使用此功能,因为它使我无法控制更新周期。但是,这证明了我的递归逻辑有效。)
  • 以递归方式计算节点是否有近邻(一个距离单位),如果是,则询问节点是否有近邻并将其移开。失败很严重,因为确保节点在分流操作之前运行checkNeighbour动作的唯一方法是将它们作为一组SKAction运行,并且SKAction的评估周期与普通代码不同,因此有效地是

    let result = checkNearNeighbour(for:currentNode,at:currentNodeIndex)   // checkNearNeighbour递归运行,并且仅在评估整个链时才返回值

    切换结果{   正确的情况:     allNodes.insert(node,at:index)

的顺序不正确,这意味着在之前插入了一个新节点,前一个节点完成了对附近邻居的检查,在这种情况下,新插入的节点将被计为附近邻居,并且原来的邻居被分流了两次。

(所有这些计算都在SKScene内部进行,所以我没有更好的移动它们的地方。大节点是我在其后插入新节点的节点,最右边的节点已检查了邻居两次,因此两次移动。) double shunt

在这一点上,我没有主意。我需要一种方法a)可视地插入节点,b)将其插入基础数组。我不愿屈服于递归(这似乎是合理的解决方案,但是它行不通),但是我现在看不到实现这一目标的另一种方法,至少没有一种方法不涉及使自己陷入困境。

更新

根据Knight0fDragon's的建议,我现在首先将节点插入阵列,并开始检查在同一位置是否还有另一个节点。 (这意味着使用moveTo而不是moveBy,因为moveBy非常不精确,因此您需要舍入该位置)。这对于单次插入非常有用,但是如果您快速插入节点,则先前的节点不会足够快地移开路径(与基于atPoint的递归相同的问题);由于SpriteKit和Cocoa处于不同的周期,因此似乎只有在最后一个节点移入位置后才触发下一个插入的方法。

我的基本递归函数(减去安全性)是

func checkNearNeighbour(for node: SKSpriteNode, index: Int) -> Bool{

         let nextNode = allNodes[nodeIndex + 1]

    guard (nextNode.position.x == node.position.x) else {return false}

    let nextPosition = CGPoint(x: nextNode.position.x + nodeDistance, y: nextNode.position.y)

    let moveAction = SKAction.move(to: nextPosition, duration: 0.5)
    let checkNext = SKAction.run {
         self.calculateNearNeighbour(for: nextNode, index: nodeIndex + 1)
    }

    nextNode.run(SKAction.sequence([moveAction, checkNext]))
return true     
} 

我看不到有任何办法可以延迟对newNode的下一次调用(该调用只是将节点插入到数组中并运行checkNearNeighbour),直到该函数最终返回为止。

0 个答案:

没有答案