user4909608
user4909608

Reputation:

Setting a name to an SKSpriteNode?

I am using the following code to generate a random image for the player in my game.

var playerTexture = [SKTexture]()

        playerTexture.append(SKTexture(imageNamed: “red”))
        playerTexture.append(SKTexture(imageNamed: “blue”))
        playerTexture.append(SKTexture(imageNamed: “green”))


        let rand = Int(arc4random_uniform(UInt32(playerTexture.count)))
        let chosenColor = playerTexture[rand] as SKTexture
        let playerSkin = chosenColor

The code above generates a random SKTexture (red, blue or green) called playerSkin.

    player = SKSpriteNode(texture: playerSkin)
    player.size = CGSize(width: 50, height: 50)
    player.position = location
    self.addChild(player)
    player.name = chosenColor.description

Then this next part of the code creates the player as an SKSpriteNode and assigns it a random texture of red, blue or green. BUT the main things is the code assigns the player.name to the randomly chosen image using:

player.name = chosenColor.description

Then I check the name of the player using print.

 print(player.name)

However, when I check the name of the player, it appears as one of the following depending on what random image was chosen:

Optional(" \'red\' (120 x 120)")

Optional(" \'blue\' (120 x 120)")

Optional(" \'green\' (120 x 120)")

My images are called "red", "blue" and "green" and are located in Assets.xcassets folder in Xcode.

My images are 120 x 120 but why are these long random names appearing? How can I set either "red", "blue" or "green" as the name of the player only?

I need the name to be EXACTLY "red", "blue" or "green" because I want to use the player.name later for a different function.

Upvotes: 4

Views: 1296

Answers (3)

Alain T.
Alain T.

Reputation: 42143

If you're just starting with SpriteKit, I would suggest that you create specialized subclasses of SKSpriteNode and keep all behaviour and concerns inside them. Over time you'll find that the whole game logic is going to be much simpler to implement and maintain.

public class PlayerNode:SKSpriteNode
{
   static let colorNames           = ["red","blue","green"]
   static let textures:[SKTexture] = PlayerNode.colorNames.map(){ SKTexture(imageNamed:$0) }

   init(randomAtLocation location:CGPoint)
   {
      let rand = Int(arc4random_uniform(UInt32(PlayerNode.colorNames.count)))
      super.init( texture: PlayerNode.textures[rand], 
                    color: UIColor.clearColor(), 
                     size: CGSize(width: 50, height: 50)
                )
      name     = PlayerNode.colorNames[rand]
      position = location
   }

   public required init?(coder aDecoder: NSCoder) { super.init(coder:aDecoder) }
}

So your player initializing code could be as simple as :

let player = PlayerNode(randomAtLocation:location)
self.addChild(player)

Upvotes: 1

Alessandro Ornano
Alessandro Ornano

Reputation: 35392

The only way to get a filename from SKTexture is by using the Textual Representation For Classes.

Swift make it easy to convert a custom class to a string (e.g. for use with print) via the CustomStringConvertible protocol. (a clear improvement over earlier implementations)

This is an example:

class X : CustomStringConvertible  {
  var description: String{
    return "This is class X"
  }
}

print(X()) //output is: "This is class X"

So, if you make a:

print(SKTexture())

your actual output in Swift 2.2 will be:

<SKTexture> '(null)' (0 x 0)

where null is the filename.

To obtain your filename you can do:

let filename = chosenColor.description.characters.split{$0 == " "}.map(String.init)[1].stringByReplacingOccurrencesOfString("\'", withString: "") as! NSString

Output:

red.png

Advantages - easy to do, you can get the real filename used by your SKTexture

Disadvantages - It's not elegant, finally you parse a string from a class which could will change his description structure (for example a new element can be added to the description and the filename could be in the position 2 instead of the actual index 1 after <SKTexture>) in future iOS release's or Swift version's, but this might happen also to other parts of your code.

Upvotes: 1

claassenApps
claassenApps

Reputation: 1147

There may be a better way to do this, but this is the first thing I thought of - make the playerTexture variable an array of tuples containing the texture and the name you want to give it:

 var playerTexture = [(SKTexture, String)]()

  playerTexture.append((SKTexture(imageNamed: “red”), "red"))
  playerTexture.append((SKTexture(imageNamed: “blue”), "blue"))
  playerTexture.append((SKTexture(imageNamed: “green”), "green"))

  let rand = Int(arc4random_uniform(UInt32(playerTexture.count)))
  let chosenColor = playerTexture[rand].0 as SKTexture
  let colorName = playerTexture[rand].1
  let playerSkin = chosenColor

  player = SKSpriteNode(texture: playerSkin)
  player.size = CGSize(width: 50, height: 50)
  player.position = location
  self.addChild(player)
  player.name = colorName

Upvotes: 2

Related Questions