SpriteKit:如何检测从节点外部开始的节点上的触摸

时间:2017-11-29 09:45:37

标签: ios sprite-kit touch sknode

SKNode A是SKNode B的父母。

如果触摸在SKNode B内部开始,则会调用touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)函数。

但是,如果触摸在SKNode B之外开始但移入SKNode B,则touchesMoved函数永远不会被调用。

一种选择是处理SKNode A内的所有触摸事件。

但是,SKNode A中包含许多节点。理想情况下,我们可以将触摸功能推送到每个子节点,而不是处理SKNode A中的所有节点。

是否有可能捕获SKNode B内部发生的触摸事件,即使它们是从SKNode B之外开始的?

1 个答案:

答案 0 :(得分:2)

当你点击touchesBegan方法时,你的触摸仅限于该节点的坐标系,直到它结束。移动到另一个节点不会将坐标系更改为新节点。如果B是唯一需要触摸的节点,那么您可以添加一个子节点来覆盖整个场景,以确保B被触发。

class TouchNode : SKSpriteNode
{
    //if you need to override other inits do it here
    convenience init(withSize size:CGSize)
    {
       self.init(color:UIColor(red:0,green:0,blue:0,alpha:0.1),size: size)
       isUserInteractionEnabled = true

    }

    override func touchesBegan(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesBegan(touches:touches, withEvent:event)
    } 

    override func touchesMoved(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesMoved(touches:touches, withEvent:event)
    } 

    override func touchesEnded(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesEnded(touches:touches, withEvent:event)
    } 

    override func touchesCancelled(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesCancelled(touches:touches, withEvent:event)
    } 

}

然后在NodeB类中:

required init(coder aDecoder:NSCoder)
{
    super.init(coder:aDecoder)
    DispatchQueue.main.async{
        self.addChild(TouchNode(withSize:self.scene!.size))
    }
}
override func touchesBegan(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    //do stuff
} 

override func touchesMoved(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    //do stuff
} 

override func touchesEnded(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    //do stuff
} 

override func touchesCancelled(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    //do stuff
} 

编辑:误读问题,但留下答案以防其他人需要从节点内部转到外部。

想一想,你想触摸nodeB之外的nodeB,这没有意义。就像我在呼吸空气,你哭着说我在戳你。但是如果你绝对需要超出边界,那么当你触摸它超出节点本身时,将一个子节点添加到精灵中,并确保将触摸恢复到父节点

class TouchNode : SKSpriteNode
{
    //if you need to override other inits do it here
    convenience init(withSize size:CGSize)
    {
       self.init(color:UIColor(red:0,green:0,blue:0,alpha:0.1),size: size)
       isUserInteractionEnabled = true

    }

    override func touchesBegan(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesBegan(touches:touches, withEvent:event)
    } 

    override func touchesMoved(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesMoved(touches:touches, withEvent:event)
    } 

    override func touchesEnded(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesEnded(touches:touches, withEvent:event)
    } 

    override func touchesCancelled(touches: Set<UITouches>, withEvent event: UIEvent?) { 
        parent!.touchesCancelled(touches:touches, withEvent:event)
    } 

}

然后在NodeB类中:

lazy var touchNode = TouchNode(withSize:self.scene!.size)

override func touchesBegan(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    addChild(touchNode)
    //do other stuff
} 
override func touchesEnded(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    touchNode.removeFromParent()
    //do other stuff
} 

override func touchesCancelled(touches: Set<UITouches>, withEvent event: UIEvent?) { 
    touchNode.removeFromParent()
    //do other stuff
}