SpriteKit:如何检测从节点外部开始的节点上的触摸
Posted
技术标签:
【中文标题】SpriteKit:如何检测从节点外部开始的节点上的触摸【英文标题】:SpriteKit: How to detect touches on node that began outside of node 【发布时间】:2017-11-29 09:45:36 【问题描述】: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 之外?
【问题讨论】:
你要覆盖 NodeB 内部的 touchesBegan 吗? @ThrowingSpoon 是的 【参考方案1】:当您点击 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
【讨论】:
谢谢!澄清一下,我同意你的看法,但这不是目标。 :) 目标是仅在节点 B 内部捕获事件。问题是如果触摸在 B 内部,如果它们在 B 外部开始 将被忽略(即,从 C 开始,然后转到 B)。 哦,我读错了问题,当然节点 B 内部的 touchesMoved 不会被调用,没有 touchesBegan 就不能使用 touchesMoved。你需要做与这个答案相反的事情,在你的 touchesmoved 上,检查你的孩子被触摸并传递信息 我需要检查,但我很确定如果您从节点内部开始并移动到外部,touchesMoved 也不会在外部调用,它仅限于节点的坐标系被触摸 如果 nodeB 是唯一需要触摸的节点,则此答案适用于修改(只需在 init 之后添加 touchNode [在初始化期间执行此操作将使场景为零] 并且永远不要删除它) 不是你的错,这意味着问题的措辞不够清楚。 :) 同意,正如问题中提到的,似乎唯一的选择是节点 A 处理所有接触并踢到节点 B。希望看看是否可以将所有内容放入节点 B 并保持节点 A 清洁(因为节点 A 需要处理很多其他的东西)。以上是关于SpriteKit:如何检测从节点外部开始的节点上的触摸的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SpriteKit 检测节点是不是离开屏幕 [重复]