如何从单击返回SKSpriteNode子类对象

时间:2015-11-28 13:52:24

标签: swift sprite-kit subclassing

我有来自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构建项目但我在日志中打印出乱码。

以下是枚举和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
    }

1 个答案:

答案 0 :(得分:2)

方法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)
    }
}

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