Spritekit 无尽的跑步者父 SKNode

Posted

技术标签:

【中文标题】Spritekit 无尽的跑步者父 SKNode【英文标题】:Spritekit endless runner parent SKNode 【发布时间】:2016-08-31 19:34:21 【问题描述】:

我对 swift 很熟悉,但我已经开始涉足 spritekit。我一直在关注有关创建无尽跑步者的教程。作者采用的方法是创建一个包含所有子节点的单个 SKNode。然后移动该容器节点,而不是单独移动所有子节点。但让我感到困惑的是容器节点没有与之关联的大小,所以我对它的工作原理/原因感到有些困惑,而作者并没有真正解释它。

所以我们有

    let containerNode = SKNode()
    let thePlayer = Player("image":"player") //SKSpriteNode
    let inc = 0
    override func didMoveToView()
        self.anchorPoint = CGPointMake(0.5,0)
        addChild(containerNode )
       containerNode.addChild(player)
         moveWorld()
    

   func moveWorld()
      let moveWorldAction = SKAction.moveByX(-screenWidth, y:0, duration:6)
     let block = SKAction.runBlock(movedWorld)
      let seq = SKAction.sequence([moveWorldAction,block])
      let repeatAction = SKAction.repeatActionForever(seq)
      containerNode.runAction(repeatAction)
   

   func movedWorld() 
     inc = inc + 1
     addObjects()

   

   func addObjects() 
   let obj = Object()
   containerNode.addChild(obj)
   let ranX = arc4random_uniform(screenWidth)
   let ranY = arc4random_uniform(screenHeight)
   obj.position = CGPointMake(screenWidth * (inc + 1) + ranX, ranY) 
   

我在上面的代码中省略了一些从 int 到 float 的转换,但对于我想理解的点来说这不是必需的。

我明白为什么在创建新对象时我们会按增量进行倍数,但我不明白的是 containerNode 没有大小,那么为什么它的子节点会显示?这是最有效的方法吗?

我假设这只是为了方便而不是单独移动所有其他对象,但它没有大小的事实让我感到困惑。

【问题讨论】:

我喜欢把 SKNodes 想象成宇宙,它在无限膨胀 【参考方案1】:

由于SKNode 没有被渲染,它不需要(或没有) size 属性。只有可见的SKNode 子类(SKLabelNodeSKShapeNode 等)需要大小(显式声明或隐式计算)。例如,SpriteKit 需要知道具有 20 x 20 纹理的 SKSpriteNode 的大小才能正确渲染它。您可以使用SKNodecalculateAccumulatedFrame 方法来确定其节点树中所有后代(除了其他SKNodes)的总大小(一个矩形)。

【讨论】:

【参考方案2】:

如果我正确理解了 SKNode 的文档,这一小节应该会回答您的问题:

节点树中的每个节点都为其提供一个坐标系 孩子们。将子节点添加到节点树后,将其定位 通过设置其位置在其父坐标系内 特性。节点的坐标系可以缩放和旋转 更改其 xScale、yScale 和 zRotation 属性。当一个节点的 坐标系被缩放或旋转,应用此变换 节点自己的内容和其后代的内容。 Source

再一次,如果我没看错的话,似乎当一个节点被添加到一个节点树时,它继承了它的父坐标系。所以默认情况下containerNodeself 在这种情况下大小相同。

同样根据 SKNode 的frame 属性:

框架是包含节点内容的最小矩形, 考虑到节点的 xScale、yScale 和 zRotation 特性。 Source

这听起来像如果没有设置框架,它需要最小的矩形(在这种情况下为self,或者它可能被理解为它是containerNode 的孩子我不确定)作为它自己的框架。

无论如何,它都是从另一个 SKNode 继承而来的。

【讨论】:

SKNode 无法从其父级继承其大小,因为它没有大小。此外,只有frameorigin(位置)属性用于SKNodes。框架的 size 属性始终为 (width:0, height:0)。

以上是关于Spritekit 无尽的跑步者父 SKNode的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GameplayKit/SpriteKit 中有效地为实体和组件建模

如何加速无尽的跑步者

为无尽的跑步游戏创建动态大小的 SKSpriteNode 平台

如何让节点永远朝一个方向移动?

仅在矩形物理体的一侧检测碰撞 - Swift3

移动 SKNodes 和 SKSpriteNodes