繁体   English   中英

Spritekit- DidBeginContact没有被调用

[英]Spritekit- DidBeginContact not being called

我注意到很多人都遇到了这个问题。 我确保在didMove函数中具有self.physicsWorld.contactDelegate = self ,但是它仍然无法正常工作。 这是我的代码:

class PoolTableScene: SKScene, SKPhysicsContactDelegate {

  struct PhysicsCatagory {

    static let None : UInt32 = 0 //0
    static let OrangeBall : UInt32 = 0b1 //1
    static let BlueBall : UInt32 = 0b10 //2
    static let PokeBall : UInt32 = 0b100 //3
    static let Border : UInt32 = 0b1000 //4
    static let All : UInt32 = UInt32.max

  }


  let ballPoke = SKSpriteNode(imageNamed:"pokeBall")
  let ballBlue = SKSpriteNode(imageNamed:"blueBall")
  let ballOrange = SKSpriteNode(imageNamed: "orangeBall")
  //var lastTouch: CGPoint? = nil


  override func didMove(to view: SKView) {

    self.physicsWorld.contactDelegate = self

    self.physicsWorld.gravity = CGVector(dx: 0, dy: -9.8)

    //used to set gravity


    //creates body for sprite that will lock the objects to a specific area
    let sceneBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    sceneBody.friction = 0 //This will make the ball bounce naturally off the edges of the scenBody
    self.physicsBody = sceneBody // make physics only affect whats in sceneBody - NEED PHYSICS BODY UNLESS IT WON'T BE AFFECTED BY PHYSICS
    self.physicsBody?.categoryBitMask = PhysicsCatagory.Border
    self.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.OrangeBall | PhysicsCatagory.PokeBall
    self.physicsBody?.contactTestBitMask = PhysicsCatagory.None

    ballPoke.name = "ballPoke"
    ballPoke.size = CGSize(width: 50, height: 50)
    ballPoke.anchorPoint = CGPoint(x:0.5, y:0.5)
    ballPoke.position = CGPoint(x: self.frame.size.width*0.25, y:self.frame.size.height/2)
    ballPoke.zPosition = 100
    ballPoke.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics
    ballPoke.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics
    ballPoke.physicsBody?.restitution = 1 // sets bounciness of ball
    ballPoke.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball
    ballPoke.physicsBody?.categoryBitMask = PhysicsCatagory.PokeBall
    ballPoke.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.Border
    ballPoke.physicsBody?.contactTestBitMask = PhysicsCatagory.OrangeBall

    self.addChild(ballPoke)


    ballBlue.name = "ballBlue"
    ballBlue.size = CGSize(width: 50, height: 50)
    ballBlue.anchorPoint = CGPoint(x:0.5, y:0.5)
    ballBlue.position = CGPoint(x: self.frame.size.width*0.50, y:self.frame.size.height/3)
    ballBlue.zPosition = 100
    ballBlue.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics
    ballBlue.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics
    ballBlue.physicsBody?.restitution = 1 // sets bounciness of ball
    ballBlue.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball
    ballBlue.physicsBody?.categoryBitMask = PhysicsCatagory.BlueBall
    ballBlue.physicsBody?.collisionBitMask = PhysicsCatagory.OrangeBall | PhysicsCatagory.PokeBall | PhysicsCatagory.Border
    ballBlue.physicsBody?.contactTestBitMask = PhysicsCatagory.None

    self.addChild(ballBlue)

    ballOrange.name = "ballOrange"
    ballOrange.size = CGSize(width: 50, height: 50)
    ballOrange.anchorPoint = CGPoint(x:0.5, y:0.5)
    ballOrange.position = CGPoint(x: self.frame.size.width*0.75, y:self.frame.size.height/2)
    ballOrange.zPosition = 100
    ballOrange.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics
    ballOrange.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics
    ballOrange.physicsBody?.restitution = 1 // sets bounciness of ball
    ballOrange.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball
    ballOrange.physicsBody?.categoryBitMask = PhysicsCatagory.OrangeBall
    ballOrange.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.Border
    ballOrange.physicsBody?.contactTestBitMask = PhysicsCatagory.PokeBall

    self.addChild(ballOrange)

  }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //Finds the position where user touches screen
    for touch: AnyObject in touches {

      let positionOfTouch = touch.location(in: self)

      //drags ball to where user touches screen
      let dragBallAction = SKAction.move(to: CGPoint(x: positionOfTouch.x, y: positionOfTouch.y), duration: 0.5)
      ballOrange.run(dragBallAction)

    }

  }


  func didBeginContact(contact: SKPhysicsContact) {

    print("contact")

    var contactBody1: SKPhysicsBody
    var contactBody2: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {

      contactBody1 = contact.bodyA
      contactBody2 = contact.bodyB
    }
    else// else almost never gets called but still add it to function

    {
      contactBody1 = contact.bodyB
      contactBody2 = contact.bodyA
    }

    //this uses the catagories set up in above struct (1 = Square, 2 = Ball)
    if ((contactBody1.categoryBitMask == 1) && (contactBody2.categoryBitMask == 3)) {

      //if the ball contact the square, remove the ball
      contactBody2.node!.removeFromParent()


    }


  }

}

我遇到了同样的问题,因为我不太熟悉ContactA和ContactB的工作原理,所以给每个对象起了一个名字,然后检查这两个对象是否发生碰撞。

func didMoveToView(view: SKView) {

       objectA = self.childNodeWithName("ObjectA") as! SKSpriteNode!
       objectB = self.childNodeWithName("ObjectB") as! SKSpriteNode!
}

 func didBeginContact(contact: SKPhysicsContact) {

        let contactA: SKPhysicsBody = contact.bodyA
        let contactB: SKPhysicsBody = contact.bodyB

        let nodeA = contactA.node as! SKSpriteNode
        let nodeB = contactB.node as! SKSpriteNode

        if nodeA.name == "ObjectA" && nodeB.name == "ObjectB" {

               //do something
        }

    }

阅读我对这个问题的回答SpriteKit-使某些SpriteNode在不禁用其物理实体的情况下不会发生碰撞 ,该实体描述了碰撞和接触之间的区别。

还要尝试实现我的checkPhysics()函数(源在同一答案中),该函数将分析您的场景并列出哪些节点与其他节点发生碰撞,以及哪些节点在联系其他节点时会通知。

对于我拥有的4个SKSPriteNodes(名为shape_blueSquare,shape_redCircle,shape_purpleSquare,shape_greenRect和shape_yellowTriangle)以及一个围绕屏幕的边框(称为“ Screen_edge”)的PhysicalDemo,输出将类似于此。

Optional("shape_blueSquare") collides with Optional("Screen_edge")
Optional("shape_blueSquare") collides with Optional("shape_redCircle")
Optional("shape_blueSquare") collides with Optional("shape_purpleSquare")
Optional("shape_blueSquare") collides with Optional("shape_greenRect")
Optional("shape_redCircle") collides with Optional("Screen_edge")
Optional("shape_redCircle") collides with Optional("shape_blueSquare")
Optional("shape_redCircle") notifies when contacting Optional("shape_purpleSquare")
Optional("shape_redCircle") collides with Optional("shape_greenRect")
Optional("shape_redCircle") notifies when contacting Optional("shape_greenRect")
Optional("shape_purpleSquare") collides with Optional("Screen_edge")
Optional("shape_purpleSquare") collides with Optional("shape_greenRect")
Category for Optional("shape_greenRect") does not appear to be set correctly as 4294967295
ptional("shape_greenRect") collides with Optional("Screen_edge")
Optional("shape_yellowTriangle") collides with Optional("Screen_edge")
Optional("shape_yellowTriangle") notifies when contacting Optional("shape_redCircle")
Optional("shape_yellowTriangle") collides with Optional("shape_greenRect")
Optional("shape_yellowTriangle") notifies when contacting Optional("shape_greenRect")

检测碰撞的属性是接触测试位掩码,这就是为什么它刚刚通过的原因,我认为您的碰撞位掩码和接触测试位掩码彼此混淆

接触测试是检测接触的方法,而碰撞位掩码允许物体彼此通过

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM