为什么在我能够获得所需的位置之前,我总是必须将精灵的位置更改为其他位置

时间:2016-02-28 09:38:17

标签: ios swift sprite-kit position coordinates

我个人认为这是真的 真的 很奇怪。

我刚刚使用SpriteKit开发游戏。我创建了一个SKSpriteNode的子类,以创建一个精灵,显示游戏剩余的时间,分数等。我称之为GameBanner

我现在正试图在横幅的左上角放置一个SKLabelNode。我不知道它的确切位置所以我写了这个:

timerTitle.position = //CGPointMake(CGRectGetMinX(self.frame) + 
    timerTitle.frame.width / 2 + 20, CGRectGetMaxY(self.frame) - 
    self.frame.height / 2 - 20)
// timerTitle is the label node that shows "Time Left"

但我只能在屏幕上看到横幅的背景图片,而不是"剩下的时间"。我想这是因为不知怎的,我将timerTitle的位置设置在横幅之外。

然后我想,嗯,这对我来说应该是多大的麻烦,让我们来试试,试试和错误"这!

我首先尝试使用(0,0)。它将标签放在中间位置。然后我尝试了这些:

  1. ( - 100,0) - 标签不可见("也许它太远了?"我想)
  2. ( - 40,0) - 大约在中心的标签,向左稍微偏移("如果-40 这个小左,那么-100就可以了!&# 34;,我想)
  3. ( - 100,0) - 标签可见,似乎在正确的位置。 ("等一下!为什么第一次没有工作?",我想)
  4. (同样的事情发生在我尝试使用(-160,0)和(-160,20)时,即第一次看不见,将其改为另一个值并运行它,将其改回( - 160,0)并且它起作用了)
  5. 我希望您能通过屏幕截图了解我的问题:

    这是我第一次将位置设置为(-160,20):

    enter image description here

    然后我把它改成(-160,0),它出现了:

    enter image description here

    之后,我把它改回(-160,20)并且它神奇地起作用了!

    enter image description here

    以下是GameBanner类:

    class GameBanner: SKSpriteNode {
        let timerTitle = SKLabelNode(text: "Time Left:")
        let timerLabel = SKLabelNode(text: "60")
        let collectedBlocksLabel = SKLabelNode(text: "Collected Blocks")
        let scoreLabel = SKLabelNode(text: "Score:")
    
        override init(texture: SKTexture?, color: UIColor, size: CGSize) {
            super.init(texture: texture, color: color, size: size)
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        //Call this initializer with Position: (302.08, 860.78), Size: (604.16, 100.0) to reproduce
        convenience init(position: CGPoint, size: CGSize) {
            self.init(texture: SKTexture(imageNamed: "banner"), color: UIColor.clearColor(), size: size)
            self.position = position
            configureLabels(timerTitle, timerLabel, collectedBlocksLabel, scoreLabel)
            // This is the part that doesn't work as I have said above
            timerTitle.position = CGPointMake(-160, 20)
    
            addChild(timerTitle)
            //addChild(timerLabel)
            //addChild(collectedBlocksLabel)
            //  addChild(scoreLabel)
    
            zPosition = 10000
        }
    
        private func configureLabels(labels: SKLabelNode...) {
            for label in labels {
                label.fontColor = UIColor.whiteColor()
                label.fontName = "Chalkduster"
                label.fontSize = 25
            }
        }
    }
    

    这是横幅的背景图片。也许这很重要:

    enter image description here

1 个答案:

答案 0 :(得分:2)

我认为您的问题与ignoresSiblingOrder属性有关。

目前,你有这样的事情:

父级(即GameBanner)将zPosition设置为10000。

label(timerTitle)添加到父级,并将默认的zPosition设置为0.0,这意味着,渲染(全局)zPosition将为10000 + 0 = 10000.意味着,它有时会在(下方)之前呈现,有时在其父母之后(上图)。

尝试明确设置标签的zPosition,将其置于其父级上方:

 convenience init(position: CGPoint, size: CGSize) {
        //...
        timerTitle.zPosition = 1
       //...
        zPosition = 10000
    }

现在,全局渲染zPositiot将为10000 + 1 = 10001,意味着该标签将始终位于横幅图像的顶部。

关于ignoresSiblingOrder财产:

  

默认值为NO,表示多个节点共享时   在相同的z位置,这些节点在a中排序和渲染   确定性秩序。父母在他们的孩子面前呈现,并且   兄弟姐妹按数组顺序呈现。当此属性设置为   是的,确定时忽略树中节点的位置   渲染顺序。同一z节点的渲染顺序   position是任意的,每次新帧都可以改变   渲染。当忽略兄弟顺序和父顺序时,SpriteKit会应用   额外的优化以提高渲染性能。如果你需要   您必须以特定和确定的顺序呈现节点   设置这些节点的z位置。

有关如何呈现节点树的更多信息:

Creating The Node Tree