使用flatMap枚举SpriteKit节点

时间:2016-06-27 05:34:12

标签: ios swift sprite-kit

我尝试使用以下内容获取某个类的所有节点:

let enemies = children.flatMap { $0 as? SomeEnemyClass }

结果是一个空数组。我想明白为什么我没有得到任何结果。 enumerateChildNodesWithName可以工作,但它没有列出我认为可能会有所帮助的父/子关系。谢谢!

以下是代码:敌人有一个简单的类,一个用敌对象替换场景编辑器中节点的级别管理器,以及GameScene.swift。一切都被分配到一个世界节点。

敌人等级

class Enemy: SKSpriteNode {
   func spawn(parentNode:SKNode, position: CGPoint, size: CGSize = CGSize(width: 50, height: 50)) {
      parentNode.addChild(self)
      self.size = size
      self.position = position
      self.name = "enemy"
      self.physicsBody = SKPhysicsBody(circleOfRadius: size.width / 2)
      self.physicsBody?.affectedByGravity = false
      self.physicsBody?.categoryBitMask = PhysicsCategory.enemy.rawValue
      self.physicsBody?.contactTestBitMask = PhysicsCategory.hero.rawValue
      self.physicsBody?.collisionBitMask = 0
   }
}

关卡经理

    class LevelManager
    {
       let levelNames:[String] = ["Level1"]
       var levels:[SKNode] = []

       init()
       {
          for levelFileName in levelNames {
             let level = SKNode()
             if let levelScene = SKScene(fileNamed: levelFileName) {
             for node in levelScene.children {
                switch node.name! {
                   case "enemy":
                   let enemy = Enemy()
                   enemy.spawn(level, position: node.position)
                   default: print("Name error: \(node.name)")
                }
             }
           levels.append(level)
          }
       }
   func addLevelsToWorld(world: SKNode)
   {
      for index in 0...levels.count - 1 {
         levels[index].position = CGPoint(x: -2000, y: index * 1000)
         world.addChild(levels[index])
      }
   }
 }

GameScene.swift - didMoveToView

world = SKNode()
world.name = "world"
addChild(world)

levelManager.addLevelsToWorld(self.world)
levelManager.levels[0].position = CGPoint(x:0, y: 0)

3 个答案:

答案 0 :(得分:1)

mapflatMap将一个数组转换为另一个数组,你真正要做的就是过滤你的子节点以寻找敌人。请改用filter

let enemines = children.filter { $0 is SomeEnemyClass }

那就是说,我没有看到你的示例代码不起作用的原因。

以下是此代码工作的示例。 enter image description here

此代码仅在您拥有从SKNode派生的真实类时才有效。使用节点名称字符串来识别节点类型更为常见。如果你的敌人有一个恒定的字符串名称,这将有效。

let enemies = children.filter { $0.name == "SomeEnemy" }

答案 1 :(得分:1)

你说

let enemies = children.flatMap { $0 as? SomeEnemyClass }
     

结果是一个空数组。我想明白为什么我没有得到任何结果。 enumerateChildNodesWithName工作

首先是这段代码

let enemies = children.flatMap { $0 as? Enemy }

是正确的,它确实返回Enemy的数组。特别是childrenEnemy内的所有对象或Enemy的子类。

查找

enter image description here

为什么不为你工作?

你说enumerateChildNodesWithName为你工作。这让我觉得你没有Enemy个孩子的物品。您只需为SKNode(s)分配了名称enemy

答案 2 :(得分:0)

我学到的是节点树实际上是一棵树,您必须开始查看右侧分支以获得结果。我的问题的答案是:

let enemies = childNodeWithName("//level")!.children.flatMap { ($0 as? SomeEnemyClass) }

let enemies = childNodeWithName("//level")!.children.filter { $0 is SomeEnemyClass }

这不是我的问题的答案,但它也有效......

 self.enumerateChildNodesWithName("//*") {
       node, stop in
       if (node.name == "enemy") {
          print(node)
       }
    }

感谢所有提供意见的人。它让我指出了正确的方向。