如何禁用两个 SKSpriteNodes 之间的联系?

Posted

技术标签:

【中文标题】如何禁用两个 SKSpriteNodes 之间的联系?【英文标题】:How to Disable contact between two SKSpriteNodes? 【发布时间】:2016-02-25 23:09:23 【问题描述】:

由于某种原因,在下面的代码中,当食物(豌豆)相互接触时,敌人细菌会移动它们。我没有对它们进行编码来测试彼此的接触。有什么帮助吗?我试图让这两种精灵不可能发生碰撞。

import SpriteKit
var apple=SKSpriteNode()

class GameScene: SKScene, SKPhysicsContactDelegate 
    var bg=SKSpriteNode()
    var peas=SKSpriteNode()
    var bacteria=SKSpriteNode()
    var bactys_Y=[SKSpriteNode]()
    var bactys_X=[SKSpriteNode]()
    var border=CGRect()
   // var gandolf=SKSpriteNode()
    enum ColliderType:UInt32
        case Bug=1
        case Food=2
        case Enemy=4
        case Gandolf=8
    

    override func didMoveToView(view: SKView) 
        border=CGRect(x: 0, y: self.frame.height, width: self.frame.width, height: self.frame.height-200)
        //gandolf.physicsBody=SKPhysicsBody(edgeLoopFromRect: border)
        let bactPic=SKTexture(imageNamed: "bacteria.png")
        /* Setup your scene here */
        //bg info
        self.physicsWorld.contactDelegate=self
        let bg_texture=SKTexture(imageNamed: "wood-texture-pattern.jpg")
        bg=SKSpriteNode(texture: bg_texture)
        bg.position=CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        bg.size.height=self.frame.height
        bg.size.width=self.frame.width
       // self.addChild(bg)
        //bug info
        let applePic=SKTexture(imageNamed:"bug.png")
        apple=SKSpriteNode(texture:applePic)
        apple.position=CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))

        print(self.frame.width)
       // let bactPic=SKTexture(imageNamed: "bacteria.png")
        //peas info
        let peas_texture=SKTexture(imageNamed: "peas.png")
        peas=SKSpriteNode(texture: peas_texture)
       // peas.position=CGPointMake(200,300)
        peas.physicsBody=SKPhysicsBody(circleOfRadius: peas_texture.size().width/4)
        apple.physicsBody=SKPhysicsBody(circleOfRadius:applePic.size().width/2)
        peas.physicsBody?.affectedByGravity=false
        apple.physicsBody?.affectedByGravity=false
        bg.zPosition=1
        apple.zPosition=2
        peas.zPosition=3
        apple.physicsBody!.categoryBitMask=ColliderType.Bug.rawValue
        apple.physicsBody!.contactTestBitMask=ColliderType.Food.rawValue
        peas.physicsBody!.categoryBitMask=ColliderType.Food.rawValue
        peas.physicsBody!.contactTestBitMask=ColliderType.Bug.rawValue
        bacteria.physicsBody=SKPhysicsBody(circleOfRadius: bactPic.size().width*0.06/2)
        bacteria.physicsBody!.categoryBitMask=ColliderType.Enemy.rawValue
        bacteria.physicsBody!.contactTestBitMask=ColliderType.Bug.rawValue
     //   gandolf.physicsBody?.categoryBitMask=ColliderType.Gandolf.rawValue
    //    gandolf.physicsBody?.categoryBitMask=ColliderType.Enemy.rawValue
        peas.setScale(0.4)
        apple.setScale(0.5)
        // bacteria info
      //  gandolf.color=UIColor.blackColor()
      //  self.addChild(gandolf)


        self.addChild(apple)
      //  self.addChild(peas)
        _=NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: Selector("spawnBacteria"), userInfo: nil, repeats: true)
        spawnBacteria()
        spawnFood()


    
    func didBeginContact(contact: SKPhysicsContact) 
      //  peas.removeFromParent()
      //  spawnFood()
        let first=contact.bodyA
        let second=contact.bodyB
        if first.categoryBitMask==ColliderType.Bug.rawValue || second.categoryBitMask==ColliderType.Bug.rawValue
            if first.categoryBitMask==ColliderType.Food.rawValue || second.categoryBitMask==ColliderType.Food.rawValue
                peas.removeFromParent()
                spawnFood()
            
        
        if first.categoryBitMask==ColliderType.Bug.rawValue || second.categoryBitMask==ColliderType.Bug.rawValue
            if first.categoryBitMask==ColliderType.Enemy.rawValue || second.categoryBitMask==ColliderType.Enemy.rawValue
                print("DEATH")
            
        

    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 
       /* Called when a touch begins */


    

    override func update(currentTime: CFTimeInterval) 
        /* Called before each frame is rendered */
       // print("x: "+String(apple.position.x))
       // print("y: "+String(apple.position.y))
        for node:SKSpriteNode in bactys_X
            if node.position.x<=0
                print("collide")
                node.physicsBody?.velocity=CGVector(dx:0, dy:0)
                node.physicsBody?.applyImpulse(CGVector(dx:6, dy:0))
            else if node.position.x>=self.frame.size.width-3
                node.physicsBody?.velocity=CGVector(dx:0,dy:0)
                node.physicsBody?.applyImpulse(CGVector(dx:-6,dy:0))
            
        
        for node:SKSpriteNode in bactys_Y
            if node.position.y>=self.frame.size.height-3
                node.physicsBody?.velocity=CGVector(dx:0,dy:0)
                node.physicsBody?.applyImpulse(CGVector(dx:0,dy:-6))
            else if node.position.y<=200
                node.physicsBody?.velocity=CGVector(dx:0,dy:0)
                node.physicsBody?.applyImpulse(CGVector(dx:0,dy:6))
            
        
    
    func spawnFood()
        let peas_texture=SKTexture(imageNamed: "peas.png")
        peas=SKSpriteNode(texture: peas_texture)
        peas.physicsBody=SKPhysicsBody(circleOfRadius: peas_texture.size().width/4)
        peas.zPosition=3
        peas.physicsBody?.affectedByGravity=false
        peas.physicsBody?.categoryBitMask=ColliderType.Food.rawValue
        peas.physicsBody?.contactTestBitMask=ColliderType.Bug.rawValue
        let x=CGFloat(arc4random_uniform(UInt32(self.frame.size.width-40)+20))
        let y=CGFloat(arc4random_uniform(UInt32(self.frame.size.height-20-200))+200)
        //print(self.frame.size.width)
        print("height: "+String(self.frame.size.height))
        print("x: "+String(x))
        print("y: "+String(y))
        peas.position=CGPointMake(x,y)
        peas.setScale(0.4)
        self.addChild(peas)
    
    func spawnBacteria()
        let bactPic=SKTexture(imageNamed: "bacteria.png")
        bacteria=SKSpriteNode(texture: bactPic)
        bacteria.physicsBody=SKPhysicsBody(circleOfRadius: bactPic.size().width*0.06/2)
        bacteria.physicsBody?.affectedByGravity=false
        bacteria.physicsBody?.categoryBitMask=ColliderType.Enemy.rawValue
        bacteria.physicsBody?.contactTestBitMask=ColliderType.Bug.rawValue
       // bacteria.physicsBody?.contactTestBitMask=ColliderType.Gandolf.rawValue
        bacteria.zPosition=4
        let x=CGFloat(arc4random_uniform(UInt32(self.frame.size.width-40)+20))
        let y=CGFloat(arc4random_uniform(UInt32(self.frame.size.height-20-200))+200)
        bacteria.position=CGPointMake(x,y)
        bacteria.setScale(0.06)
        let decide=Int(arc4random_uniform(3))

        self.addChild(bacteria)
        if decide==0
            //move left
           //  let move=SKAction.moveByX(-6, y: 0, duration: 0.1)
            // let start=SKAction.repeatActionForever(move)
             //bacteria.runAction(start)
            bacteria.physicsBody?.applyImpulse(CGVector(dx: -6,dy: 0))
            bactys_X.append(bacteria)

        else if decide==1
            //move right
          //  let move=SKAction.moveByX(6, y: 0, duration: 0.1)
            // let start=SKAction.repeatActionForever(move)
            // bacteria.runAction(start)
            bacteria.physicsBody?.applyImpulse(CGVector(dx: 6, dy: 0))
            bactys_X.append(bacteria)
        else if decide==2
            //move up
          //  let move=SKAction.moveByX(0, y: 6, duration: 0.1)
            // let start=SKAction.repeatActionForever(move)
            //  bacteria.runAction(start)
            bacteria.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 6))
            bactys_Y.append(bacteria)
        else
            //move down
           //  let move=SKAction.moveByX(0, y: -6, duration: 0.1)
            // let start=SKAction.repeatActionForever(move)
          //  bacteria.runAction(start)
            bacteria.physicsBody?.applyImpulse(CGVector(dx: 0,dy: -6))
            bactys_Y.append(bacteria)
        


    

【问题讨论】:

【参考方案1】:

默认情况下,物理体的碰撞位掩码设置为 0xFFFFFFFF(与所有对象交互),其动态属性设置为 true。查看您的代码,您似乎没有设置它们,因此它使用默认值。

您必须设置这些属性才能达到您想要的结果

...physicsBody.dynamic = false
...physicsBody.collisionBitMask = //set to something

【讨论】:

我的荣幸,快乐的编码

以上是关于如何禁用两个 SKSpriteNodes 之间的联系?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测其他 SKSpriteNodes 的子节点的相交节点

如何检测 SKSpriteNode 和 SKView SpriteKit 之间的冲突

使用 SpriteKit 缩放 SkSpriteNodes

如何将一组skspritenodes一起移动

为啥我的 SKSpriteNodes 不会出现在场景中?

SpriteKit SKSpriteNodes 管理