Функция DidBegin не работает - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь сделать игру ковбой / стрелок. Мне нужно столкновение между снарядом (исходящим от первого ковбоя), чтобы ударить второго ковбоя. Однако функция 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))


}

Ковбой2 Физика:

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 голосов
/ 23 мая 2019

Это может быть связано с тем, что вы не выбрали делегата PhysWorld:

  • Убедитесь, что ваш класс реализует SKPhysicsContactDelegate:

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
    ......
    
    }
    //Or whatever your class looks like
    
  • В вашем didMove:

    override func didMove(to view: SKView) {
    
        self.scene?.physicsWorld.contactDelegate = self
      ....
    
    }
    
0 голосов
/ 23 мая 2019

Не сразу понятно, почему это не работает.

Можете ли вы добавить эту функцию в свой код, и когда вы настроите всю физику, сделайте вызов 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)")}
            }
        }
    }
}

}

...