touchesBegin没有在Sprit Node上调用

时间:2016-08-22 01:48:49

标签: swift sprite-kit swift3

我的SpritNodes在我的场景中,我希望在触摸它时调用方法。我的节点isUserInteractionEnabled设置为true,但触摸节点时仍然没有调用touchesBegan。 (注意:我使用的是Swift 3.0)

代码:

    import SpriteKit

class MainScene: SKScene, SKPhysicsContactDelegate {

    var didStart = false
    var background = SKSpriteNode(imageNamed: "background")
    var backDrop = SKShapeNode()
    var emailNodes: [SKSpriteNode] = []

    let emailCatagory: UInt32 = 0x1 << 0
    let dropCatagory: UInt32 = 0x1 << 1

    override func sceneDidLoad() {
        startCountDown()
    }

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

        background.position = CGPoint(x: frame.midX, y:frame.midY)
    }

    public func startCountDown(){
        var times = 4

        let countdownTimer = SKLabelNode()
        countdownTimer.text = "3"
        countdownTimer.position = CGPoint(x: frame.midX, y: frame.midY)
        countdownTimer.fontSize = 120.0
        countdownTimer.fontName = "Lao MN"
        countdownTimer.fontColor = UIColor.black()

        backDrop = SKShapeNode()
        backDrop = SKShapeNode(rectOf: CGSize(width: frame.width, height: 100))
        backDrop.position = CGPoint(x: frame.midX, y: 10)
        backDrop.physicsBody = SKPhysicsBody(rectangleOf: backDrop.frame.size)
        //backDrop.size = CGSize(width: 1000, height: 2)
        backDrop.physicsBody?.affectedByGravity = false
        backDrop.physicsBody?.usesPreciseCollisionDetection = true
        backDrop.name = "backDrop"
        backDrop.physicsBody?.collisionBitMask = 0
        backDrop.physicsBody?.categoryBitMask = dropCatagory

        addChild(countdownTimer)
        addChild(backDrop)
        //addChild(background)

        Timer.every(1.2.seconds) { (timer: Timer) in
            if(times<=0){
                timer.invalidate()
                countdownTimer.removeFromParent()
                self.didStart = true
                self.startDropping()
            }else{
                print("\(times)")
                times = times - 1
                countdownTimer.text = "\(times)"
            }
        }
    }

    func startDropping(){
        Timer.every(1.2.seconds) { (timer: Timer) in
            let which = Int(arc4random_uniform(2) + 1)
            let ee = self.getEmailNode(type: which)
            self.addChild(ee)
            ee.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: -5.0))
        }
    }

    func getEmailNode(type: Int) -> SKSpriteNode{
        var email = SKSpriteNode()
        if(type == 1){
            email = SKSpriteNode(imageNamed: "normal_email")
            email.name = "normal_email"
        }
        if(type == 2){
            email = SKSpriteNode(imageNamed: "classified_email")
            email.name = "classified_email"
        }
        email.setScale(3)
        email.position = CGPoint(x: getRandomColumn(), y: frame.height)
        email.physicsBody = SKPhysicsBody(rectangleOf: email.frame.size)
        email.physicsBody?.usesPreciseCollisionDetection = true
        email.physicsBody?.categoryBitMask = emailCatagory
        email.isUserInteractionEnabled = true
        email.physicsBody?.affectedByGravity = false
        email.physicsBody?.collisionBitMask = 0
        email.physicsBody?.contactTestBitMask = emailCatagory | dropCatagory
        emailNodes.append(email)
        return email
    }

    func getRandomColumn() -> CGFloat{
        let which = Int(arc4random_uniform(3) + 1)
        let gg = frame.size.width/3
        switch(which){
        case 1:
            return gg / 2
        case 2:
            return frame.midX
        case 3:
            return (gg * 3) - gg / 2
        default:
            return (gg * 3) + gg / 2
        }
    }

    func didBegin(_ contact: SKPhysicsContact) {
        if (contact.bodyA.categoryBitMask == dropCatagory) &&
            (contact.bodyB.categoryBitMask == emailCatagory) {
            let node = contact.bodyB.node as! SKSpriteNode
            node.removeFromParent()
            while emailNodes.contains(node) {
                if let itemToRemoveIndex = emailNodes.index(of: node) {
                    emailNodes.remove(at: itemToRemoveIndex)
                }
            }
        }
    }

    func doesContainNode(sk: SKSpriteNode) -> Bool {
        for it in emailNodes{
            if(it == sk){
                return true
            }
        }
        return false
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        enumerateChildNodes(withName: "//*", using:
            { (node, stop) -> Void in
                print("\(node.name)")
                print("\(node)")
                if((node.name?.contains("email")) != nil){
                    print("Touched!")
                }
        })
    }

}

3 个答案:

答案 0 :(得分:1)

您应该尝试以下操作,以便能够获取用户的位置并知道何时触摸精灵。在touchesEnabled函数中添加以下内容。

for touch in touches {
    let userTouch = touch.locationInNode(self)
}

然后使用以下方法检查精灵是否被触摸:

node.containsPoint(userTouch)

看看是否有效。你设置代码的方式,你可能需要在检查它是否为零后立即嵌套上面的函数。对于userInteractionEnabled,在使用上述代码时我根本不使用它。

答案 1 :(得分:1)

您不希望在任何节点上设置userInteractionEnabled,您只希望在场景中使用touchesBegan。仅在为节点创建子类时才使用'security.role_hierarchy' => [ 'ROLE_ADMIN' => [ 'ROLE_USER', ], 'ROLE_SUPER_ADMIN' => [ 'ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH' ] ], 'security.access_rules' => [ [ '^.*$', 'IS_AUTHENTICATED_ANONYMOUSLY' ], [ '^/account', 'ROLE_USER' ], [ '^/admin', 'ROLE_ADMIN' ] ] ,这样您就可以在子类文件中使用$app->get('/admin', function () use ($app) { return 1; })->bind('admin'); 。发生了什么事情是你的触摸进入你的节点并被吸收,什么都不做,并且由于节点吸收它而被场景忽略。

编辑:抱歉@MarkBrownsword我没有看到你的评论,如果你把它作为答案发布,我会upvote并删除我的答案。

答案 2 :(得分:1)

我找到了解决方案。我删除了isUserInteractionEnabled,但仍未调用touchesBegan。所以我浏览了“email”节点的每个属性,由于某种原因,以下属性使得touchesBegan不会被调用。

email.physicsBody?.affectedByGravity = false
email.physicsBody?.collisionBitMask = 0

所以我删除了那些,现在正在调用touchesBegan