Swift多节点访问

假设我们在1000次左右添加相同的节点,如下面的代码所示。 有没有什么办法可以访问每一个平台?

例如,如果PlatformCategoryPlayerCategory之间有碰撞,碰撞的PlatformCategory应该将其颜色更改为绿色并运行SKAction

编辑:感谢旋风,我可以让与玩家碰撞的平台变成绿色,而其他所有的变成红色。 现在我需要正确设置碰撞,这意味着我只想让PlayerPlatform上碰撞Platform

例如,玩家从1.平台跳到2.平台。 在跳跃的时候,不要碰到第二个平台,只有在通过之后。

 class GameScene: SKScene, SKPhysicsContactDelegate { let PlayerCategory : UInt32 = 0x1 << 1 let PlatformCategory : UInt32 = 0x1 << 2 var Platform: SKSpriteNode! var Player: SKSpriteNode! override func didMoveToView(view: SKView) { /* Setup your scene here */ self.physicsWorld.contactDelegate = self self.physicsBody?.velocity = CGVectorMake(0, 0) ..... SpawnPlayer() generatePlatforms() } func SpawnPlatforms(position: CGPoint)->SKSpriteNode{ Platform = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: self.frame.size.width, height: 25)) Platform.position = position Platform.zPosition = 1 Platform.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: self.frame.size.width, height: 25)) Platform.physicsBody?.dynamic = false Platform.physicsBody?.restitution = 0.0 Platform.physicsBody?.allowsRotation = false Platform.physicsBody?.usesPreciseCollisionDetection = true Platform.physicsBody?.categoryBitMask = PlatformCategory Platform.physicsBody?.contactTestBitMask = PlayerCategory Platform.physicsBody?.collisionBitMask = PlayerCategory return Platform } func generatePlatforms(){ for i in 1...1000{ let position = CGPoint(x: self.frame.size.width / 2, y: 140 * CGFloat(i)) let platform = SpawnPlatforms(position) self.addChild(platform) } } func didBeginContact(contact: SKPhysicsContact) { let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask let platform = contact.bodyB.node as! SKSpriteNode switch(contactMask) { case PlayerCategory | PlatformCategory: //either the contactMask was the bro type or the ground type print("Contact Made0") if(Player.position.y >= platform.position.y && Player.position.y <= platform.position.y + Player.size.height){ Player.physicsBody?.collisionBitMask = PlatformCategory platform.color = SKColor.greenColor() } default: return } } func didEndContact(contact: SKPhysicsContact) { let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask switch(contactMask) { case PlayerCategory | PlatformCategory: //either the contactMask was the bro type or the ground type print("Contact Made0") default: return } } 

正如我所说,为了检测接触,以改变平台的颜色,你必须做一些事情:

  • 符合SKPhysicsDelegate协议
  • 正确设置physicsWorld的contactDelegate属性
  • 实现didBeginContact方法

符合SKPhysicsDelegate协议

这个任务的语法很简单:

 class GameScene: SKScene,SKPhysicsContactDelegate {//your GameScene properties and methods go here...} 

符合协议意味着类必须实现该协议所需的方法。 SKPhysicsDelegate协议的具体方法是didBeginContact和didEndContact。 如果你看看头文件,你会看到这个:

 protocol SKPhysicsContactDelegate : NSObjectProtocol { optional func didBeginContact(contact: SKPhysicsContact) optional func didEndContact(contact: SKPhysicsContact) } 

即使这些方法是可选的,我们也需要它们来获得描述联系人的联系对象。

设置physicsWorld联系人委托属性

唯一需要的代码是:

 self.physicsWorld.contactDelegate = self //self is a scene (eg. GameScene) 

所以当物理世界发生物理接触时,我们应该得到某种程度的通知。 根据文档, contactDelegate属性是在发生该联系时调用的代理 。 通过将场景设置为联系人委托,我们将联系处理的责任委托给它。 这应该提到didBeginContact。

下面是你应该如何实现它(可能有更多的方法):

 func didBeginContact(contact: SKPhysicsContact) { var firstBody, secondBody: SKPhysicsBody if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { firstBody = contact.bodyA secondBody = contact.bodyB } else { firstBody = contact.bodyB secondBody = contact.bodyA } if ((firstBody.categoryBitMask & CharacterCategory) != 0 && (secondBody.categoryBitMask & PlatformCategory != 0)) { //secondBody would be a platform } } } 

在这里,你可以很容易地改变一个平台的颜色:

 let platform = secondBody.node as SKSpriteNode platform.color = UIColor.redColor() 

或者你可以改变所有平台的颜色:

 self.enumerateChildNodesWithName("platform", usingBlock: { node, stop in var platformNode = node as SKSpriteNode platformNode.color = UIColor.redColor() }) 

另外我看到你正在使用这个问题的代码:

https://stackoverflow.com/a/31454044/3402095

所以我编辑了它(改变了didBeginContact)来向你展示如何将精灵的颜色改为红色。