DidBegin函数未运行

时间:2019-05-21 17:16:11

标签: swift sprite-kit

我正在尝试制作牛仔/枪手游戏。我需要弹丸(来自第一个牛仔)之间发生碰撞才能击中第二个牛仔。但是,didBegin函数没有被运行/调用。

我曾经尝试使用以前游戏中的代码来弄乱物理机构,但没有成功。 showPhysics = true。

物理类别:

struct PhysicsCategory {
    static let none              :UInt32 = 0
    static let cowboy1Physics    :UInt32 = 0x1 << 1
    static let cowboy2Physics    :UInt32 = 0x1 << 1
    static let projectile1Physics:UInt32 = 0x1 << 0
    static let projectile2Physics:UInt32 = 0x1 << 0
}

Fire Bullet1:

func fireProjectile1() {
    let projectile1 = SKSpriteNode(imageNamed: "bullet1")
    projectile1.position = cowboyNo1.position
    projectile1.position.x += 5
    projectile1.size = CGSize(width: projectile1.size.width / 4,           height: projectile1.size.height / 4)
    self.addChild(projectile1)
    projectile1.physicsBody = SKPhysicsBody(rectangleOf: projectile1.size )
    projectile1.physicsBody?.isDynamic = true
    projectile1.physicsBody?.categoryBitMask = PhysicsCategory.projectile1Physics
    projectile1.physicsBody?.contactTestBitMask = PhysicsCategory.cowboy2Physics
    projectile1.physicsBody?.collisionBitMask =  PhysicsCategory.none
    projectile1.physicsBody?.usesPreciseCollisionDetection = true



    projectile1.zPosition = 1
    var actionArray = [SKAction]()

    actionArray.append(SKAction.move(to: CGPoint(x: size.height + 1500, y: cowboyNo1.position.y), duration: TimeInterval(1.5)))

   actionArray.append(SKAction.wait(forDuration: 1))
    actionArray.append(SKAction.removeFromParent())
    print("fire")
    projectile1.run(SKAction.sequence(actionArray))


}

Cowboy2物理学:

func createCowboyNo2() {
    cowboyNo2.position = CGPoint(x: 1800, y: 200)
    cowboyNo2.zPosition = 1
    cowboyNo2.size = CGSize(width: cowboyNo2.size.width / 2, height: cowboyNo2.size.height / 2)

    // Cowboy2 physics
    cowboyNo2.physicsBody = SKPhysicsBody(rectangleOf: cowboyNo2.size) // 1
    cowboyNo2.physicsBody?.isDynamic = true // 2
    cowboyNo2.physicsBody?.categoryBitMask = PhysicsCategory.cowboy2Physics // 3
    cowboyNo2.physicsBody?.contactTestBitMask = 2 // 4
    cowboyNo2.physicsBody?.collisionBitMask = PhysicsCategory.none
    cowboyNo2.physicsBody?.usesPreciseCollisionDetection = true
    physicsWorld.gravity = .zero
    addChild(cowboyNo2)

}

DidBegin:

func didBegin(_ contact: SKPhysicsContact) {
    // 1
    var firstBody:SKPhysicsBody
    var secondBody:SKPhysicsBody
    print("test")
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
        firstBody = contact.bodyA
        secondBody = contact.bodyB
        print("contact body's")
    }
    else{
        firstBody = contact.bodyB
        secondBody = contact.bodyA
        print("more contact bodys")
    }
    if (firstBody.categoryBitMask & PhysicsCategory.projectile1Physics) != 0 && (secondBody.categoryBitMask & PhysicsCategory.cowboy2Physics) != 0{
        projectileDidCollideWithCowboy2(nodeA: firstBody.node as! SKSpriteNode, nodeB: secondBody.node as! SKSpriteNode)
        print("remove child")
    }

DidCollideWithCowboy函数:

func projectileDidCollideWithCowboy2(nodeA: SKSpriteNode, nodeB:     SKSpriteNode) {
    print("hit")
    nodeA.removeFromParent()
    nodeB.removeFromParent()
    score1 += 1
}

预期的输出是要删除项目符号,并在控制台上打印“ test”,但没有打印任何内容。射弹正朝牛仔开火。似乎应该在运行时未在代码中完全调用didBegin函数。

2 个答案:

答案 0 :(得分:0)

它为什么不起作用尚不清楚。

您可以将此功能添加到代码中吗?设置完所有物理后,请致电checkPhysics(),它将列出您定义的碰撞和联系方式:

//MARK: - Analyse the collision/contact set up.
func checkPhysics() {

    // Create an array of all the nodes with physicsBodies
    var physicsNodes = [SKNode]()

    //Get all physics bodies
    enumerateChildNodes(withName: "//.") { node, _ in
        if let _ = node.physicsBody {
            physicsNodes.append(node)
        } else {
            print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.")
        }
    }

    //For each node, check it's category against every other node's collion and contctTest bit mask
    for node in physicsNodes {
        let category = node.physicsBody!.categoryBitMask
        // Identify the node by its category if the name is blank
        let name = node.name != nil ? node.name! : "Category \(category)"

        let collisionMask = node.physicsBody!.collisionBitMask
        let contactMask = node.physicsBody!.contactTestBitMask

        // If all bits of the collisonmask set, just say it collides with everything.
        if collisionMask == UInt32.max {
            print("\(name) collides with everything")
        }

        for otherNode in physicsNodes {
        if (node.physicsBody?.dynamic == false) {
            print("This node \(name) is not dynamic")
        }
            if (node != otherNode) && (node.physicsBody?.isDynamic == true) {
                let otherCategory = otherNode.physicsBody!.categoryBitMask
                // Identify the node by its category if the name is blank
                let otherName = otherNode.name != nil ? otherNode.name! : "Category \(otherCategory)"

                // If the collisonmask and category match, they will collide
                if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) {
                    print("\(name) collides with \(otherName)")
                }
                // If the contactMAsk and category match, they will contact
                if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")}
            }
        }
    }
}

}

答案 1 :(得分:0)

可能是因为您尚未选择PhysicWorld委托:

  • 确保您的课程实现了SKPhysicsContactDelegate

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
    ......
    
    }
    //Or whatever your class looks like
    
  • 在您的didMove中:

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