SpriteKit:在运行时更新SKLabelNode文本时遇到问题(2种方法)

时间:2015-05-31 11:34:39

标签: sprite-kit

我想根据用户点击节点来设置标签文字。我尝试了两种方法,但都没有按预期工作。

方法#1:全局声明SKLabelNode,在运行时更新sklabelnode.text。 代码:

import SpriteKit

class GameScene: SKScene {

  //Level 0
  var q0Label:SKLabelNode!
  var q1Label:SKLabelNode!
  let gem = SKSpriteNode(imageNamed:"Destiny_Gem")
  let energy = SKSpriteNode(imageNamed: "Destiny_Energy")
  let money = SKSpriteNode(imageNamed: "Destiny_Money")

  override func didMoveToView(view: SKView) {
    //Level 0 - Choose your Destiny
    //Add a label to the scene
    q0Label = SKLabelNode(fontNamed: "Courier")
    q0Label.text = "Why do you want to be a Doctor?"
    q0Label.fontSize = 30
    q0Label.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    self.addChild(q0Label)

    q1Label = SKLabelNode(fontNamed: "Courier")
    q1Label.fontSize = 25
    q1Label.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.3)

    //Position the sprites
    gem.position = CGPoint(x:frame.size.width * 0.2, y: frame.size.height * 0.4)
    gem.zPosition = 2
    [gem.setScale(0.5)]
    gem.name = "gem"
    energy.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.4)
    energy.zPosition = 2
    [energy.setScale(0.5)]
    energy.name = "energy"
    money.position = CGPoint(x:frame.size.width * 0.8, y: frame.size.height * 0.4)
    money.zPosition = 2
    [money.setScale(0.25)]
    money.name = "money"

    //Add sprites to scene
    addChild(gem)
    addChild(energy)
    addChild(money)
  }

  override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    /* Called when a touch begins */

    for touch: AnyObject in touches {
      let location = (touch as! UITouch).locationInNode(self)
      if let theName = self.nodeAtPoint(location).name {
        if theName == "gem" {
          q1Label.text = "Like my parents before me, it is my destiny."
          self.addChild(q1Label)
        }
        else if theName == "energy" {
          q1Label.text = "The people of the world need my help."
          self.addChild(q1Label)
        }
        else if theName == "money" {
          q1Label.text = "I want to be rich and famous."
          self.addChild(q1Label)
        }
      }
    }
  }
}

问题:这将在您第一次单击节点时起作用,但是下次单击时,应用程序将崩溃,并显示以下错误消息: &#34;尝试添加已经存在父错误的SKNode&#34;

然后,我在SO上阅读了关于不全局声明对象的各种解决方案。这导致了方法#2。

方法#2:有条件地声明标签。 代码:

  override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    /* Called when a touch begins */

    for touch: AnyObject in touches {
      let location = (touch as! UITouch).locationInNode(self)
      if let theName = self.nodeAtPoint(location).name {
        if theName == "gem" {
          var q1Label:SKLabelNode!
          q1Label = SKLabelNode(fontNamed: "Courier")
          q1Label.fontSize = 25
          q1Label.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.3)
          q1Label.text = "Like my parents before me, it is my destiny."
          //set destiny variable = gem
          self.addChild(q1Label)
        }
        else if theName == "energy" {
          var q1Label:SKLabelNode!
          q1Label = SKLabelNode(fontNamed: "Courier")
          q1Label.fontSize = 25
          q1Label.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.3)
          q1Label.text = "The people of the world need my help."
          //set destiny variable = energy
          self.addChild(q1Label)
        }
        else if theName == "money" {
          var q1Label:SKLabelNode!
          q1Label = SKLabelNode(fontNamed: "Courier")
          q1Label.fontSize = 25
          q1Label.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.3)
          q1Label.text = "I want to be rich and famous."
          //set destiny variable = money
          self.addChild(q1Label)
        }
      }
    }
  }
}

问题:这只会在彼此的顶部创建标签;我不知道如何清理之前创建的任何内容。

1 个答案:

答案 0 :(得分:1)

在这种情况下重新创建标签实际上是不必要的。您只想根据单击的按钮更新标签。你唯一需要做的就是在didMoveToView方法中创建这两个标签并相应地更新它们,就像这样(只需复制/通过这段代码试试):

import SpriteKit

class GameScene: SKScene {

    //Level 0
    var q0Label:SKLabelNode!
    var q1Label:SKLabelNode!
    let gem = SKSpriteNode(imageNamed:"Destiny_Gem")
    let energy = SKSpriteNode(imageNamed: "Destiny_Energy")
    let money = SKSpriteNode(imageNamed: "Destiny_Money")

    override func didMoveToView(view: SKView) {
        //Level 0 - Choose your Destiny
        //Add a label to the scene
        q0Label = SKLabelNode(fontNamed: "Courier")
        q0Label.text = "Why do you want to be a Doctor?"
        q0Label.fontSize = 30
        q0Label.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        self.addChild(q0Label)

        q1Label = SKLabelNode(fontNamed: "Courier")
        q1Label.fontSize = 25
        q1Label.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.3)
        q1Label.text = ""
         self.addChild(q1Label)
        //Position the sprites
        gem.position = CGPoint(x:frame.size.width * 0.35, y: frame.size.height * 0.4)
        gem.zPosition = 2
        [gem.setScale(0.5)]
        gem.name = "gem"
        energy.position = CGPoint(x:frame.size.width * 0.3, y: frame.size.height * 0.4)
        energy.zPosition = 2
        [energy.setScale(0.5)]
        energy.name = "energy"
        money.position = CGPoint(x:frame.size.width * 0.4, y: frame.size.height * 0.4)
        money.zPosition = 2
        [money.setScale(0.25)]
        money.name = "money"

        //Add sprites to scene
        addChild(gem)
        addChild(energy)
        addChild(money)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */

        for touch: AnyObject in touches {
            let location = (touch as UITouch).locationInNode(self)
            if let theName = self.nodeAtPoint(location).name {
                if theName == "gem" {
                    q1Label.text = "Like my parents before me, it is my destiny."

                }
                else if theName == "energy" {
                    q1Label.text = "The people of the world need my help."

                }
                else if theName == "money" {
                    q1Label.text = "I want to be rich and famous."

                }
            }
        }
    }
}

不要多次重新添加这些标签。关于你得到的错误...请记住,节点当时只能有一个父节点,这就是为什么你得到的错误,说明某个标签已经有父节点。