Swift多节点访问
假设我们在1000次左右添加相同的节点,如下面的代码所示。 有没有什么办法可以访问每一个平台?
例如,如果PlatformCategory
和PlayerCategory
之间有碰撞,碰撞的PlatformCategory
应该将其颜色更改为绿色并运行SKAction
。
编辑:感谢旋风,我可以让与玩家碰撞的平台变成绿色,而其他所有的变成红色。 现在我需要正确设置碰撞,这意味着我只想让Player
在Platform
上碰撞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)来向你展示如何将精灵的颜色改为红色。