Swift3 如何使用SpriteKit向图像添加字典值?

Swift3 如何使用SpriteKit向图像添加字典值?,swift3,sprite-kit,Swift3,Sprite Kit,((编辑4:成功使卡片翻转。在节点上使用.contains并运行SKAction序列。我如何为卡片创建三种状态?元组听起来很有趣。未翻转、翻转、突出显示翻转。它在所有卡片向下加载(完成)时加载,我要取消卡片翻转(完成),然后再次点击它以高亮显示。第二次点击时,它高亮显示自身和顶部的猜测词。然后将两个字符串连接在底部的标签中,并激活下一个按钮(尚未构建)。成功匹配键[value]==a[B]后,得分+=1。越来越近!) ((编辑3:使用拆分键和值更新didMove。现在可以将标题作为第一个键,我可

((编辑4:成功使卡片翻转。在节点上使用.contains并运行SKAction序列。我如何为卡片创建三种状态?元组听起来很有趣。未翻转、翻转、突出显示翻转。它在所有卡片向下加载(完成)时加载,我要取消卡片翻转(完成),然后再次点击它以高亮显示。第二次点击时,它高亮显示自身和顶部的猜测词。然后将两个字符串连接在底部的标签中,并激活下一个按钮(尚未构建)。成功匹配键[value]==a[B]后,得分+=1。越来越近!)

((编辑3:使用拆分键和值更新didMove。现在可以将标题作为第一个键,我可以将第一个值放在左上角的卡片上作为测试。进行中。现在我只需要在触摸时清空卡片或找到翻转卡片的方法。如何完成触摸代码?触摸开始?)

((编辑2:现在从字典键值对的角度考虑,而不是仅仅从值的角度考虑。摆脱了将值分配给卡牌时查找键的问题。现在使用SKLabelNode标记卡牌。需要翻转卡牌、添加值、比较键。))

((编辑:我在GameScene.swift中制作了所有元素的代码。该文件现在包含在本文中。还更新了问题文本并删除了一些其他文本。)

我不熟悉SpriteKit和Swift 3。由于有几百万个扬声器,世界语软件并不多,所以我想为自己制作一个游戏,学习1000个世界语单词。(未显示!)

我想让每张卡片翻转以显示字典键/值中的单词value

然后查看该单词是否与所选值的wordGuess标签匹配

另外,JSON可能更适合将1000个单词分成模块化的部分,但我将在另一个时间跨越这座桥梁

// Code updated to EDIT 4
//  
//

import SpriteKit


class GameScene: SKScene {

    let guessLabel = SKLabelNode(fontNamed: "HelveticaNeue-UltraLight")
    let anotherLabel = SKLabelNode(fontNamed: "HelveticaNeue-UltraLight")

    var cardTopLeftLabel = SKLabelNode(fontNamed: "Arial-BoldMT")
    let cardTopLeft = SKSpriteNode(imageNamed: "Redcard")

    var cardTopRightLabel = SKLabelNode(fontNamed: "Arial-BoldMT")
    let cardTopRight = SKSpriteNode(imageNamed: "Redcard")

    var cardBottomLeftLabel = SKLabelNode(fontNamed: "Arial-BoldMT")
    let cardBottomLeft = SKSpriteNode(imageNamed: "Redcard")

    var cardBottomRightLabel = SKLabelNode(fontNamed: "Arial-BoldMT")
    let cardBottomRight = SKSpriteNode(imageNamed: "Redcard")

    var cardsDictionary: [String:String] = [
        "tree": "arbo",
        "forest": "arbaro",
        "spider": "araneo",
        "water": "akvo",
        "watermelon": "akvomelono",
        "school": "lerno",
        "year": "jaro",
        "grasshopper": "akrido",
        "lawn": "gazono",
        "friend": "amiko",
        "people": "homoj",
        "city": "urbo",
        "mayor": "urbestro",
        "movie": "filmo",
        "Monday": "lundo",
        "dog": "hundo"
    ]





    // not used yet
    func randomSequenceGenerator(min: Int, max: Int) -> () -> Int {
        var numbers: [Int] = []
        return {
            if numbers.count == 0 {
                numbers = Array(min ... max)
            }

            let index = Int(arc4random_uniform(UInt32(numbers.count)))
            return numbers.remove(at: index)
        }
    }



    func addLabel(spriteNode:SKSpriteNode, labelNode: SKLabelNode, cardValue: String, cardName: String) {
        labelNode.zPosition = 1
        labelNode.text = cardValue
        labelNode.name = cardName //"cardTopRightLabel"
        labelNode.fontSize = 40
        labelNode.fontColor = .black
        labelNode.position = CGPoint.init(x: cardTopLeft.size.width/4, y: 0.5)
        labelNode.isHidden = true
        spriteNode.addChild(labelNode)
    }


    override func didMove(to view: SKView) {

        if let words = self.userData?.value(forKey: "words")
        {
            print("word information contains \(words)")
        }

        // get all the card keys
        var cardKeys:[String] = []
        for (k,_) in cardsDictionary {
            cardKeys.append(k)
        }
        print("all keys are \(cardKeys)")

        // slice for four card keys
        var fourCardKeys = cardKeys[0...3]
        print("four keys are \(fourCardKeys)")

        // get keys for display
        var firstCardKey = fourCardKeys[0]
        var secondCardKey = fourCardKeys[1]
        var thirdCardKey = fourCardKeys[2]
        var fourthCardKey = fourCardKeys[3]
//        print("Card Keys are \(firstCardKey), \(secondCardKey), \(thirdCardKey), \(fourthCardKey)")

        // get the card values
        var cardsValue:[String] = []
        for (_,v) in cardsDictionary {
            cardsValue.append(v)
        }
        print(cardsValue)

        // slice for card values
        let fourCardValues = cardsValue[0...3]
        print(fourCardValues)

        // get values for display
        let firstCardValue  = fourCardValues[0]
        let secondCardValue = fourCardValues[1]
        let thirdCardValue = fourCardValues[2]
        let fourthCardValue = fourCardValues[3]
        print("Card Values are  \(firstCardValue), \(secondCardValue), \(thirdCardValue), \(fourthCardValue)")


        // put first card key into label
        guessLabel.zPosition = 1
        guessLabel.text = firstCardKey //cardKeys[0]
        guessLabel.name = "guessLabel"
        guessLabel.fontSize = 144;
        guessLabel.fontColor = .black
        //anotherLabel.position = CGPoint(x:frame.midX, y:frame.midY - 100.0)
        guessLabel.position = CGPoint(x:-2, y:233)
        addChild(guessLabel)


        anotherLabel.zPosition = 0
        anotherLabel.text = "Guess key here, values in cards"
        anotherLabel.name = "anotherLabel"
        anotherLabel.fontSize = 45;
        anotherLabel.fontColor = .blue
        //anotherLabel.position = CGPoint(x:frame.midX, y:frame.midY - 100.0)
        anotherLabel.position = CGPoint(x:-2, y:203)
        addChild(anotherLabel)


        ////////////////
        // top left card
        cardTopLeft.zPosition = 0
        cardTopLeft.size = CGSize(width: 300.0, height: 300.0)
        cardTopLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        cardTopLeft.position = CGPoint(x:-229, y:-57)
        addChild(cardTopLeft)

        addLabel(spriteNode: cardTopLeft,
                 labelNode: cardTopLeftLabel,
                 cardValue: firstCardValue,
                 cardName: "cardTopLeftLabel")


        /////////////////
        // top right card
        cardTopRight.zPosition = 1
        cardTopRight.size = CGSize(width: 300.0, height: 300.0)
        cardTopRight.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        cardTopRight.position = CGPoint(x:132, y:-57)
        addChild(cardTopRight)

        addLabel(spriteNode: cardTopRight,
                 labelNode: cardTopRightLabel,
                 cardValue: secondCardValue,
                 cardName: "cardTopRightLabel")

        ///////////////////
        // bottom left card
        cardBottomLeft.zPosition = 1
        cardBottomLeft.size = CGSize(width: 300.0, height: 300.0)
        cardBottomLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        cardBottomLeft.position = CGPoint(x:-225, y:-365)
        addChild(cardBottomLeft)

        addLabel(spriteNode: cardBottomLeft,
                 labelNode: cardBottomLeftLabel,
                 cardValue: thirdCardValue,
                 cardName: "cardBottomLeftLabel")

        ////////////////////
        // bottom right card
        cardBottomRight.zPosition = 1
        cardBottomRight.size = CGSize(width: 300.0, height: 300.0)
        cardBottomRight.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        cardBottomRight.position = CGPoint(x:132, y:-365)
        addChild(cardBottomRight)

        addLabel(spriteNode: cardBottomRight,
                 labelNode: cardBottomRightLabel,
                 cardValue: fourthCardValue,
                 cardName: "cardBottomRightLabel")

    }


    func touchDown(atPoint pos : CGPoint)
    {

    }

    func touchMoved(toPoint pos : CGPoint) {

    }

    func touchUp(atPoint pos : CGPoint) {


    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {


        guard let touch = touches.first else {
            return
        }

        let touchLocation = touch.location(in: self)
        let touchedNode = self.atPoint(touchLocation)


        func flipCard (node: SKNode, label: SKLabelNode)
        {
            label.isHidden = true

            node.run(SKAction.sequence(
                [SKAction.scaleX(to: 0, duration: 0.2),
                 SKAction.scale(to: 1, duration: 0.0),
                 SKAction.setTexture(SKTexture(imageNamed: "Redcard-blank"))
                                 ]
            ))
            label.isHidden = false
        }

        func flipCardPause (node: SKNode, interval: Double)
        {
            node.run(SKAction.wait(forDuration: interval))
            print("paused for \(interval) seconds")
        }

        func flipCardBack (node: SKNode, label: SKLabelNode)
        {
            label.isHidden = true

            node.run(SKAction.sequence(
                [SKAction.scaleX(to: 1, duration: 0.2),
                 SKAction.setTexture(SKTexture(imageNamed: "Redcard"))
                 // SKAction.scale(to: 1, duration: 0.2)


                ]
            ))
        }


        if cardTopLeft.contains(touchLocation)
        {
            flipCard(node: cardTopLeft, label: cardTopLeftLabel)
            //flipCardPause(node: cardTopLeft, interval: 3)
            //flipCardBack(node: cardTopLeft, label: cardTopLeftLabel)
        }

        if cardTopRight.contains(touchLocation)
        {
            flipCard(node: cardTopRight, label: cardTopRightLabel)

        }

        if cardBottomLeft.contains(touchLocation)
        {
            flipCard(node: cardBottomLeft, label: cardBottomLeftLabel)
        }

        if cardBottomRight.contains(touchLocation)
        {
            flipCard(node: cardBottomRight, label: cardBottomRightLabel)
        }

        for t in touches { self.touchDown(atPoint: t.location(in: self)) }

    }
那么SKLabelNode着陆了?我试试看。还需要翻转卡片,使文字不在图像上。最后,将按下的卡的键与wordGuess键文本进行比较。越来越近

编辑3:使用分割键和值更新didMove。现在可以将标题作为第一个键,我可以将第一个值放在左上角的卡片上作为测试。进步。现在我只需要在接地时把牌清空,或者想办法把它翻过来

    cardTopLeft.zPosition = 0
    cardTopLeft.size = CGSize(width: 300.0, height: 300.0)
    cardTopLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    cardTopLeft.position = CGPoint(x:-229, y:-57)
    addChild(cardTopLeft)

    cardTopLeftLabel.zPosition = 1
    cardTopLeftLabel.text = fourCardValues[0]
    cardTopLeftLabel.name = "cardTopLeftLabel"
    cardTopLeftLabel.fontSize = 40
    cardTopLeftLabel.fontColor = .black
    cardTopLeftLabel.position = CGPoint.init(x: cardTopLeft.size.width/4, y: 0.5)
    cardTopLeft.addChild(cardTopLeftLabel)

编辑4:成功使卡片翻转。在节点上使用.contains并运行SKAction序列。如何为卡创建三种状态?Tuple听起来是个有趣的主意。未翻转、翻转、翻转突出显示。它加载所有卡片(完成),我想解开卡片(完成),然后再次点击以突出显示它(帮助?)。在第二次这样做时,它突出了自己和最热门的猜测词。然后,这两个字符串连接在底部的标签中,并激活“下一步”按钮(尚未构建)。成功匹配键[value]==A[B]后,得分+=1。越来越近了!这真的很像一个匹配的游戏,但我增加了一个额外的一层翻牌

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {       

        guard let touch = touches.first else {
            return
        }

        let touchLocation = touch.location(in: self)
        let touchedNode = self.atPoint(touchLocation)


        func flipCard (node: SKNode, label: SKLabelNode)
        {
            label.isHidden = true

            node.run(SKAction.sequence(
                [SKAction.scaleX(to: 0, duration: 0.2),
                 SKAction.scale(to: 1, duration: 0.0),
                 SKAction.setTexture(SKTexture(imageNamed: "Redcard-blank"))
                                 ]
            ))
            label.isHidden = false
        }
override func touchsbegind(touch:Set,with event:UIEvent?{
保护让触摸=触摸。首先触摸{
返回
}
让touchLocation=touch.location(in:self)
让touchedNode=self.atPoint(touchLocation)
func动画卡(节点:SKNode,标签:SKLabelNode)
{
label.ishiden=true
node.run(SKAction.sequence(
[SKAction.scaleX(to:0,持续时间:0.2),
SKAction.刻度(至:1,持续时间:0.0),
SKAction.setTexture(SKTexture(图像名为:“Redcard blank”))
]
))
label.ishiden=false
}

所有SKNodes都有一个名为
userData
的字典,您可以将其写入。它是可选的NSMutableDictionary,因此您必须创建它:

    cardTopLeft.zPosition = 1
    cardTopLeft.size = CGSize(width: 300.0, height: 300.0)
    cardTopLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    cardTopLeft.position = CGPoint(x:-229, y:-57)
    cardTopLeft.userData = ["word":"tree","value","arbo"]
    addChild(cardTopLeft)
使用:

    let word = cardTopLeft.userData["word"]
    let value = cardTopLeft.userData["value"]
为了更好地理解您的问题,我将使用
SKLabelNode
作为替代方案

您可以做的是在卡片上创建
SKLabelNode
s,并将其标记为
ishiden=true
。当您准备显示单词时,只需标记
ishiden=false

    let value = SKLabelNode("arbo")
    value.isHidden = false      

    cardTopLeft.zPosition = 1
    cardTopLeft.size = CGSize(width: 300.0, height: 300.0)
    cardTopLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    cardTopLeft.position = CGPoint(x:-229, y:-57)
    cardTopLeft.addChild(value)
    addChild(cardTopLeft)


    //to reveal it
    if let label = cardTopLeft.children[0] as? SKLabelNode
    { 
        label.isHidden = false
    }

    //to use it
    if let label = cardTopLeft.children[0] as? SKLabelNode
    { 
        let value = label.text
        //compare value to dictionary of answers
    }

您可能希望为标签指定一个名称,这样就不必使用子项[0],但我将让您决定如何查找节点。

就我个人而言,我不喜欢使用userData,我认为这不是一个可读的代码

我想创建一个自定义节点,如:

class Card: SKSpriteNode {
    var value....
    var dictionary
    etc
} 
另一种解决方案是,您可以创建元组:

var cardsDictionary: [String:String] = [
        "vegetable":"legomo",
        "plant":"vegetalo",
        "actually":"efektive",
        "currently":"aktuale"
    ]
let cardTopLeft = (node:SKNode, value:Int, type:[String:String])

cardTopLeft.node = SKSpriteNode(imageNamed: "Redcard")
cardTopLeft.value = 1
cardTopLeft.type = cardsDictionary[0]

谢谢你的评论。这很有趣,我将仔细研究它,看看它是如何在每一组4张卡的节点上动态工作的。你的帖子帮助我意识到我需要在每张卡上放置密钥和值对,然后只显示值。这样我就不需要像userData这样的更多数据结构。我将y也在使用SKLabelNode。感谢你的帖子,它帮助我了解了应该采取的方向。你想让数据模块化并包含在内。只需做一个未连接到节点的键值对,你就可能会面临数据被破坏和不再存在的风险,这可能会使你的应用程序崩溃。这有点像拥有一个ID.当然你可以把它交给你妈妈保管,但是当你妈妈丢失或毁坏它时会发生什么呢?或者当别人需要看你的身份证时会发生什么,你会打电话告诉你妈妈把它带给你吗?你最好随身带着你的身份证。这就是为什么我们有钥匙链。所以卡片钥匙会帮我保管钥匙。我可以en根据切片索引导出值,并将其用于节点标签。我将在晚餐后尝试;)你的意思是什么?我想我将使用SwiftyJSON将问题编辑为JSON文件,以便获得.arra
var cardsDictionary: [String:String] = [
        "vegetable":"legomo",
        "plant":"vegetalo",
        "actually":"efektive",
        "currently":"aktuale"
    ]
let cardTopLeft = (node:SKNode, value:Int, type:[String:String])

cardTopLeft.node = SKSpriteNode(imageNamed: "Redcard")
cardTopLeft.value = 1
cardTopLeft.type = cardsDictionary[0]