【问题标题】:How to get SKSpriteNode subclassed object back from click如何从单击中获取 SKSpriteNode 子类对象
【发布时间】:2015-11-28 13:52:23
【问题描述】:

我有以下我从 SKSpriteNode 继承的对象

class PlayingCard : SKSpriteNode
{
  var suit:Int = 0
  var rank:Int = 0
  var visible:Bool = false

  init()
    {
        super.init(
         texture: SKTexture(imageNamed: "card.png"), 
         color: NSColor.blackColor(), 
         size: SKTexture(imageNamed: "card.png").size())
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func updateSprite()
    {
       if (suit == 1 && rank ==1) 
       { self.texture = SKTexture(imageNames: "ace_of_clubs.png") }
       .
       .
       .
       .
       // A bunch of switches and if's to assign the right image
    }
}

现在我初始化这个类并将它添加到我的场景中。一切正常,卡片出现。除了当我在点击后寻找self.nodeAtPoint(location) 时,我得到一个SKNode 回来!!我所有的价值观都丢失了吗?这是怎么回事?

override func mouseDown(theEvent: NSEvent) 
{
    // Called when a mouse click starts
    let location = theEvent.locationInNode(self)
    let t = self.nodeAtPoint(location)
    NSLog("%s",String(t.suit)) //<-------- Won't Compile
}

知道怎么做吗?尝试使用:t as! PlayingCard 进行类型转换会构建项目,但我在 Log 中打印出乱码。

这里是枚举和 PlayingCards 类:

enum Suits:Int
{
    case Diamond, Heart, Club, Spade
}

enum Ranks:Int
{
    case ace, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king
}

class PlayingCards : SKSpriteNode
{
    var CardRank:Ranks = Ranks.ace
    var CardSuit:Suits = Suits.Club
    var Visible:Bool = false
    //var Sprite:SKSpriteNode

    init()
    {
        super.init(texture: SKTexture(imageNamed: "b1fv.png"), color: NSColor.blackColor(), size: SKTexture(imageNamed: "b1fv.png").size())
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func updateSprite()
    {
        self.name = Description(Set: 2)

        if self.Visible
        {
            self.texture = SKTexture(imageNamed: generateSpriteFilename())
        } else {
            self.texture = SKTexture(imageNamed: "b1fv.png")
        }
    }

    func generateSpriteFilename() -> String
    {
        return self.Description(Set: 2) + ".png"
    }

    func Description(Set s:Int) -> String
    {
        var cr = ""
        var cs = ""

        switch self.CardRank
        {
        case .ace:
            cr = (s == 1) ? "ace" : "1"
            break
        case .jack:
            cr = (s == 1) ? "jack" : "j"
            break
        case .king:
            cr = (s == 1) ? "king" : "k"
            break
        case .queen:
            cr = (s == 1) ? "queen" : "q"
            break
        default:
            cr = String(self.CardRank.rawValue + 1)
        }

        switch self.CardSuit
        {
        case .Club:
            cs = (s == 1) ? "clubs" : "c"
            break
        case .Diamond:
            cs = (s == 1) ? "diamonds" : "d"
            break
        case .Heart:
            cs = (s == 1) ? "hearts" : "h"
            break
        case .Spade:
            cs = (s == 1) ? "spades" : "s"
            break
        }

        return (s == 1) ? cr + "_of_" + cs : cs + cr
    }
}

这是我填充数组的方式:

func prepareDeck() -> [PlayingCards]
    {
        var deck = [PlayingCards]()

        for i in 0...3
        {
            let s:Suits = Suits(rawValue: i)!
            for j in 0...12
            {
                let r:Ranks = Ranks(rawValue: j)!
                let c:PlayingCards = PlayingCards()
                c.CardRank = r
                c.CardSuit = s

                deck.append(c)
            }
        }

        return deck
    }

【问题讨论】:

    标签: swift sprite-kit subclassing


    【解决方案1】:

    nodeAtPoint 方法确实会返回一个 SKNode

    当然我们知道节点可能更具体,但在编译时我们只能说它将是一个SKNode

    现在,如果您认为该对象比简单的 SKNode(如 PlayingCard)更具体,您可以尝试将节点转换为您的类型。

    override func mouseDown(theEvent: NSEvent) {
        let location = theEvent.locationInNode(self)
        let node = self.nodeAtPoint(location)
    
        if let playingCard = node as? PlayingCard {            
            // here you have your PayingCard object!
            print(playingCard.suit)
        }
    }
    

    在上面的代码中,只有当检索到的节点是PlayingCard 时,才会输入IF 的主体。在这种情况下,将创建一个类型为 PlayingCard 的新常量 playingCard。 因此,在 IF 的主体内,您可以使用您在 PlayingCard 类中定义的所有方法和属性。

    【讨论】:

    • 它仍然返回乱码“¿ŒT”。 nodeAtPoint 实际上是否返回原始对象?还是只是它的 SKNode 部分?
    • 它返回完整的对象。我不明白你的意思。是否输入IF
    • 确实如此。这是我正在使用的:if let playingCard = node as? PlayingCard {NSLog("%s",String(playingCard.suit.rawValue))}(在我的项目套装中实际上是一个枚举)。这是我在日志中得到的:2015-11-28 10:58:05.376 PlayingCards[28602:2653744] ¿ŒT
    • 那么我想我们解决了第一个问题。下一个问题是为什么playingCard.suit.rawValue 产生¿ŒT。请告诉我枚举是如何定义的以及如何填充suit 属性。
    • 你是绝对正确的。我在填充 PlayingCards 类实例后立即尝试了 NSLog,但我得到了乱码。所以我可能没有正确填写。请查看枚举、类以及我如何填充它的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多