【问题标题】:Setting a name to an SKSpriteNode?将名称设置为 SKSpriteNode?
【发布时间】:2016-07-18 15:43:16
【问题描述】:

我正在使用以下代码为我的游戏中的玩家生成随机图像。

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

上面的代码生成一个名为 playerSkin 的随机 SKTexture(红色、蓝色或绿色)。

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

然后代码的下一部分将播放器创建为 SKSpriteNode,并为其分配红色、蓝色或绿色的随机纹理。但主要的是代码将 player.name 分配给随机选择的图像:

player.name = chosenColor.description

然后我使用打印检查播放器的名称。

 print(player.name)

但是,当我检查播放器的名称时,它会根据选择的随机图像显示为以下之一:

可选的("\'red\' (120 x 120)")

可选(“\'蓝色\'(120 x 120)”)

可选(“\'绿色\'(120 x 120)”)

我的图像被称为“红色”、“蓝色”和“绿色”,位于 Xcode 的 Assets.xcassets 文件夹中。

我的图像是 120 x 120,但为什么会出现这些长随机名称?如何将“red”、“blue”或“green”设置为仅播放器的名称?

我需要将名称完全设为“红色”、“蓝色”或“绿色”,因为我想稍后将 player.name 用于不同的功能。

【问题讨论】:

    标签: swift sprite-kit skspritenode


    【解决方案1】:

    可能有更好的方法来做到这一点,但这是我想到的第一件事——让 playerTexture 变量成为一个包含纹理和你想给它的名称的元组数组:

     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
    

    【讨论】:

    • 对。无法从SKTexture 本身检索名称,因此您需要存储用于创建它的字符串。 (简化的一种方法是存储字符串,并在分配chosenColor时初始化SKTexture内联。)
    • 感谢 claassenApps!这是最简单的方法!我是编码新手,所以这很完美。干杯!
    【解决方案2】:

    SKTexture 获取文件名的唯一方法是使用Textual Representation For Classes

    Swift 通过 CustomStringConvertible 协议可以轻松地将自定义类转换为字符串(例如用于打印)。 (对早期实现的明显改进)

    这是一个例子:

    class X : CustomStringConvertible  {
      var description: String{
        return "This is class X"
      }
    }
    
    print(X()) //output is: "This is class X"
    

    所以,如果你做一个:

    print(SKTexture())
    

    您在 Swift 2.2 中的实际输出将是:

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

    其中 null 是文件名。

    要获取您的文件名,您可以:

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

    输出

    red.png
    

    优势 - 简单易做,你可以得到你的SKTexture

    使用的真实文件名

    缺点 - 这并不优雅,最后你从一个类中解析一个字符串,这可能会改变他的描述结构(例如,一个新元素可以添加到描述中,文件名可以在位置 2 而不是@987654328 之后的实际索引 1 @) 在未来的 iOS 版本或 Swift 版本中,但这也可能发生在代码的其他部分。

    【讨论】:

    • 太棒了!很难跟上,但很棒。
    • 无论如何你可以使用这样的东西来浏览一个文件夹并提取所有要使用的图像,并命名后续节点吗? stackoverflow.com/questions/39811334/…
    • 我也试着给你一个答案:)
    【解决方案3】:

    如果您刚开始使用 SpriteKit,我建议您创建 SKSpriteNode 的专门子类并将所有行为和关注点保留在其中。随着时间的推移,您会发​​现整个游戏逻辑的实现和维护会变得更加简单。

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

    所以你的播放器初始化代码可以很简单:

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

    【讨论】:

    • 这是:"PlayerNode.colorNames.map(){ SKTexture(imageNamed:$0) }" 某种可以遍历所有纹理的魔法巫术吗?
    • 除了对数组voodoo的困惑之外,我必须补充一下,谢谢!代码架构技巧是无价的。谢谢!!!
    • 而且,如果你有时间......我如何更改这一行以反映正在加载的图像的大小,而不是任意的? “尺寸:CGSize(宽度:50,高度:50)”
    • 你可以使用 super.init(texture:) 没有颜色/尺寸参数。我相信它将使用纹理的大小作为默认值。您始终可以在下一行设置颜色,但我认为默认情况下它也会很清晰。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多