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



我想根据用户在节点上的点击设置标签的文本。我试过两种方法,但都没有达到预期的效果。

方法#1:全局声明SKLabelNode,更新SKLabelNode。运行时的文本。代码:
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)
        }
      }
    }
  }
}

问题:当你第一次点击一个节点时,这将工作,但是下一次点击时,应用程序将崩溃,并出现以下错误信息:"试图添加一个已经有父节点错误的SKNode "

然后我在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)
        }
      }
    }
  }
}

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

在这种情况下真的没有必要重新创建标签。您只需要根据单击哪个按钮来更新标签。你唯一需要做的就是在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."
                }
            }
        }
    }
}

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

最新更新