Swift多节点访问

时间:2015-11-11 19:52:06

标签: ios swift sprite-kit

我们假设我们将相同的节点添加大约1000次,如下面的代码所示。有没有办法访问每个平台?

例如,如果PlatformCategoryPlayerCategory之间发生碰撞,则发生碰撞的平台应将其颜色更改为绿色并运行SKAction

编辑:感谢Whirlwind,我可以让与玩家相撞的平台变为绿色,而其他所有人都保持红色。现在我需要正确设置碰撞,这意味着我只希望PlayerPlatform高于它时与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 } } 发生碰撞。

例如,播放器从1.平台跳转到2.平台。在跳跃时,它不应该在第二个平台通过之后与第二平台发生碰撞。

<Grid x:Name="SourceGrid13"
              CanDrag="True"
              DragStarting="SourceGrid_DragStarting"
              Margin="0,20,0,0">

1 个答案:

答案 0 :(得分:1)

正如我所说,要检测联系以改变平台的颜色,你必须做一些事情:

  • 符合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),向您展示如何将精灵的颜色更改为红色。