2017-09-02 60 views
-1
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")。它不这样做。我无法让我的应用程序来检测碰撞

注:要么是蓝色,红色或绿色球从屏幕和土地上的蓝色,红色或绿色的长方形顶部下降。但到目前为止,我只设置了蓝色球和红色矩形的检测碰撞代码。我希望有人能够帮助,非常感谢。

回答

0

的问题是,你在你的方法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) 
    } 
}