I have the following Object I have subclassed from 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
}
}
Now I initialize this class and add it to my scene. Everything works fine, the card shows up. Except when I look for self.nodeAtPoint(location)
after a click, I get a SKNode
back!! Are all my values lost? Whats going on here?
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
}
Any idea how to do this? Trying to type cast using: t as! PlayingCard
builds the project but I get gibberish printed in Log.
Here are the enums and the PlayingCards class:
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
}
}
Here is how I populate the array:
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
}
Th method nodeAtPoint
does return you an SKNode
.
Of course we know that node could be more specific but at compile time all we can say is that it will be an SKNode
.
Now, if you believe that the object is something more specific that a simple SKNode (like a PlayingCard
) you can try to cast the node to your type.
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)
}
}
In the code above, the body of the IF
is entered only if the retrieved node is a PlayingCard
. In this case a new constant playingCard
having the type of PlayingCard
is created.
So inside the body of the IF
you can use all the methods and properties you defined in your PlayingCard
class.