通过 SKNode 子类更新 SKLabel 文本

Updating SKLabel text through an SKNode subclass

我的目标:将成就的数量变量加一 Class,然后更新文本,使其显示在名为 "AmountLabel"[的 SKLabelNode 上=14=]

所以我有一个 SKNode 的子class 来保护我的 SKSpriteNode,它显示成就的标志和成就标题的 SKLabelNodes 以及解锁成就所需的数量,如下所示:

class Achievements: SKNode {

var achievementLabel = SKLabelNode()
var achievementTitleLabel = SKLabelNode()
var achievementNode = SKSpriteNode()

var amount = 0
var neededAmount = 0

var Image: String = "locked" {
    didSet {
       var texture = SKTexture(imageNamed: Image)
    }
}

func createAchievement() {

    let tex:SKTexture = SKTexture(imageNamed: Image)

    achievementNode = SKSpriteNode(texture: tex, color: SKColor.black, size: CGSize(width: 75, height: 75))  //frame.maxX / 20, height: frame.maxY / 20))
    achievementNode.zPosition = -10
    achievementNode.name = "AchievementNode"

    amount = 0
    neededAmount = 10

    self.addChild(achievementNode)
    self.zPosition = -11
    Achievements3.append(achievementNode)

    createAchievementLabels()
}

func createAchievementLabels() {

    achievementTitleLabel = SKLabelNode(fontNamed: "Avenir-Black")
    achievementTitleLabel.fontColor = UIColor.black;
    achievementTitleLabel.fontSize = 13 //self.frame.maxY/30
    achievementTitleLabel.position = CGPoint (x: 0, y: 45)
    achievementTitleLabel.text = "COLLECTOR"
    achievementTitleLabel.zPosition = -9
    addChild(achievementTitleLabel)

    achievementTitleLabel.name = "AchievementTitleLabel"

    achievementLabel = SKLabelNode(fontNamed: "Avenir-Black")
    achievementLabel.fontColor = UIColor.black;
    achievementLabel.fontSize = 13 //self.frame.maxY/30
    achievementLabel.position = CGPoint (x: 0, y: -50)
    achievementLabel.text = ("\(amount) / \(neededAmount)")
    achievementLabel.zPosition = -9
    addChild(achievementLabel)

    achievementLabel.name = "AmountLabel"
    AchievementLabels.append(achievementLabel)

}

func UpdateText() {

    achievementLabel.text = ("\(amount) / \(neededAmount)")

   }

}

然后将它们添加到另一个名为 AchievementMenu 的 class 中,如下所示:

for 0...12 {

     let Achievement = Achievements()
     Achievement.createAchievement()
     Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
     Achievement.zPosition = 100
     moveableArea.addChild(Achievement)
}

然后在 AchievementMenu 的另一个函数中 class 我试图通过节点树进行枚举,以便能够更新标签以将其添加到其数量变量中,然后像这样更新其文本:

 func addOneToAchievementAndUpdateText() {

    moveableArea.enumerateChildNodes(withName: "SKNode") {
        node, stop in

        let LabelAmount:Achievements = node as! Achievements

        node.enumerateChildNodes(withName: "AmountLabel") {
            node, stop in

            LabelAmount.amount += 1
            LabelAmount.UpdateText()

        }
    }
}

但每次我尝试将变量转换为实际的 class 时,它都会给我一个错误:

Could not cast value of type 'SKLabelNode' (0x10e5edb08) to 'Astrum.Achievements' (0x10c899438).

如何向金额变量加一,然后更新文本以便在屏幕上显示新金额?

为避免转换错误,您可以将节点类型检查为:

func addOneToAchievementAndUpdateText() {

    moveableArea.enumerateChildNodes(withName: "SKNode") {
        node, stop in
        print("- node type is: \(type(of: node))")
        if node is Achievements {
            let achievements = node as! Achievements
            achievements.amount += 1
            achievements.UpdateText()
        }
    }
}

如果你在行后面加上你的错误就不会出现:

Achievement.zPosition = 100

这一行:

Achievement.name = "SKNode"

P.S. 不要忘记对变量使用小写字母,以免将它们与 class 类型混淆:通常它被认为是态度不好..