【问题标题】:I am having trouble getting my app to detect a collision我无法让我的应用检测到碰撞
【发布时间】:2017-09-02 01:31:38
【问题描述】:
class GameScene: SKScene, SKPhysicsContactDelegate {

    let balls = [
        SKSpriteNode(imageNamed: "blueball.png"),
        SKSpriteNode(imageNamed: "greenball.png"),
        SKSpriteNode(imageNamed: "realredball.png"),
        ]

    let redRectangle = SKSpriteNode(imageNamed: "redrectangle.png")
    let blueRectangle = SKSpriteNode(imageNamed: "bluerectangle.png")
    let greenRectangle = SKSpriteNode(imageNamed: "greenrectangle.png")

    let blueBallCategory: UInt32 = 0x1 << 0
    let greenBallCategory: UInt32 = 0x1 << 1
    let realRedBallCategory: UInt32 = 0x1 << 2
    let redRectangleCategory: UInt32 = 0x1 << 3
    let blueRectangleCategory: UInt32 = 0x1 << 4
    let greenRectangleCategory: UInt32 = 0x1 << 5

    override func didMove(to view: SKView) {
        spawnBallsandRectangles()
        physicsWorld.contactDelegate = self
    }

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

    func didBegin(_ contact: SKPhysicsContact) {

        var firstBody: SKPhysicsBody
        var 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 == blueBallCategory 
          && secondBody.categoryBitMask == redRectangleCategory {
             print("dead")
        }
    }

    func spawnBallsandRectangles() {
        let ball = balls[Int(arc4random_uniform(UInt32(balls.count)))]
        ball.position = CGPoint(x: 0, y: 250)
        ball.size = CGSize(width: 70, height: 70)

        balls[0].physicsBody?.categoryBitMask = blueBallCategory
        balls[1].physicsBody?.categoryBitMask = greenBallCategory
        balls[2].physicsBody?.categoryBitMask = realRedBallCategory
        balls[0].physicsBody?.contactTestBitMask = redRectangleCategory

        redRectangle.position = CGPoint(x: 0, y: -600)
        redRectangle.size = CGSize(width: 200, height: 20)
        redRectangle.physicsBody?.categoryBitMask = redRectangleCategory

        blueRectangle.position = CGPoint(x: -200, y: -600)
        blueRectangle.size = CGSize(width: 200, height: 20)
        blueRectangle.physicsBody?.categoryBitMask = blueRectangleCategory

        greenRectangle.position = CGPoint(x: 200, y: -600)
        greenRectangle.size = CGSize(width: 200, height: 20)
        greenRectangle.physicsBody?.categoryBitMask = greenRectangleCategory

        self.addChild(ball)
        self.addChild(redRectangle)
        self.addChild(blueRectangle)
        self.addChild(greenRectangle)
    }

    func physics() {
        for ball in balls {
            ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height/2)
        }

        redRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
        redRectangle.physicsBody?.affectedByGravity = false
        redRectangle.physicsBody?.isDynamic = false

        blueRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
        blueRectangle.physicsBody?.affectedByGravity = false

        greenRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
        greenRectangle.physicsBody?.affectedByGravity = false

    }
}

我希望蓝色球(ball[0]) 击中redRectangle 节点并触发碰撞检测。我对其进行了编程,因此如果在蓝色球落在红色矩形上时检测到碰撞,控制台将print ("dead")。它不这样做。

注意:蓝色、红色或绿色球从屏幕顶部落下并落在蓝色、红色或绿色矩形上。但到目前为止,我只为蓝色球和红色矩形设置了检测碰撞代码。我希望有人能提供帮助,非常感谢。

【问题讨论】:

    标签: ios swift xcode sprite-kit


    【解决方案1】:

    问题是您正在为方法physics() 中的节点分配SKPhysicsBody。方法spawnBallsandRectangles() 将值分配给这些主体的categoryBitMask 属性。由于您在physics() 之前调用spawnBallsandRectangles(),因此主体还不存在,位掩码的分配失败。

    我会将所有设置代码从physics() 移动到spawnBallsandRectangles(),以便您可以在尝试为其属性赋值之前设置物理体。要让球在被触摸之前保持静止,您可以使用self.isPaused = true 暂停场景,然后稍后使用self.isPaused = false 重新开始,或者在球上使用isDynamic 属性,这样它们在被触摸之前不会是动态的。

    您可以使用这种技术来检测哪个球被触摸,然后在它被触摸后使其动态:How do I detect if an SKSpriteNode has been touched

    我使用最后一种技术重新编写了您的代码来演示。

    class GameScene: SKScene, SKPhysicsContactDelegate {
      let balls = [
        SKSpriteNode(imageNamed: "blueball.png"),
        SKSpriteNode(imageNamed: "greenball.png"),
        SKSpriteNode(imageNamed: "realredball.png"),
        ]
    
      let redRectangle = SKSpriteNode(imageNamed: "redrectangle.png")
      let blueRectangle = SKSpriteNode(imageNamed: "bluerectangle.png")
      let greenRectangle = SKSpriteNode(imageNamed: "greenrectangle.png")
    
      let blueBallCategory: UInt32 = 0x1 << 0
      let greenBallCategory: UInt32 = 0x1 << 1
      let realRedBallCategory: UInt32 = 0x1 << 2
      let redRectangleCategory: UInt32 = 0x1 << 3
      let blueRectangleCategory: UInt32 = 0x1 << 4
      let greenRectangleCategory: UInt32 = 0x1 << 5
    
      override func didMove(to view: SKView) {
        // set up all properties for balls and rectangles
        spawnBallsandRectangles()
        self.physicsWorld.contactDelegate = self
      }
    
      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // find node touched
        guard let touched = touches.first else { return }
        let position = touched.location(in: self)
        let touchedNode = self.atPoint(position)
    
        // if it's a ball then start it falling
        if touchedNode.name == "ball" {
          touchedNode.physicsBody?.isDynamic = true
        }
      }
    
      func didBegin(_ contact: SKPhysicsContact) {
        var firstBody: SKPhysicsBody
        var 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 == blueBallCategory
          && secondBody.categoryBitMask == redRectangleCategory {
          print("dead")
        }
      }
    
      /// Convenience method to set up the rectangles
      static func setupRectangle(rectangle: SKSpriteNode,
                                 category: UInt32,
                                 position: CGPoint) {
        rectangle.position = position
        rectangle.size = CGSize(width: 200, height: 20)
        let physicsBody = SKPhysicsBody(rectangleOf: rectangle.size)
        physicsBody.affectedByGravity = false
        physicsBody.isDynamic = false
        physicsBody.categoryBitMask = category
        rectangle.physicsBody = physicsBody
      }
    
      func spawnBallsandRectangles() {
        for ball in balls {
          // name them to later identify them when touched
          ball.name = "ball"
    
          // give it a physics body and freeze it
          let physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height/2)
          physicsBody.isDynamic = false
          ball.physicsBody = physicsBody
        }
    
        let ball = balls[Int(arc4random_uniform(UInt32(balls.count)))]
        ball.position = CGPoint(x: 0, y: 250)
        ball.size = CGSize(width: 70, height: 70)
    
        balls[0].physicsBody?.categoryBitMask = blueBallCategory
        balls[1].physicsBody?.categoryBitMask = greenBallCategory
        balls[2].physicsBody?.categoryBitMask = realRedBallCategory
        balls[0].physicsBody?.contactTestBitMask = redRectangleCategory
    
        GameScene.setupRectangle(rectangle: redRectangle,
                                 category: redRectangleCategory,
                                 position: CGPoint(x: 0, y: -600))
        GameScene.setupRectangle(rectangle: blueRectangle,
                                 category: blueRectangleCategory,
                                 position: CGPoint(x: -200, y: -600))
        GameScene.setupRectangle(rectangle: greenRectangle,
                                 category: greenRectangleCategory,
                                 position: CGPoint(x: 200, y: -600))
    
        self.addChild(ball)
        self.addChild(redRectangle)
        self.addChild(blueRectangle)
        self.addChild(greenRectangle)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多