检测 SKShapeNode 上的触摸是一条线
Posted
技术标签:
【中文标题】检测 SKShapeNode 上的触摸是一条线【英文标题】:Detecting Touch on SKShapeNode that is a Line 【发布时间】:2014-07-01 03:24:00 【问题描述】:我创建了一个 SKShapeNode 并为其提供了一个 CGPath。这是在 didMoveToView 中的 GameScene.swift 中:
let myNode = SKShapeNode()
let lineToDraw = CGPathCreateMutable()
CGPathMoveToPoint(lineToDraw, nil, 0, 0)
CGPathAddLineToPoint(lineToDraw, nil, 87, 120)
myNode.path = lineToDraw
myNode.strokeColor = SKColor.redColor()
myNode.lineWidth = 20
myNode.name = "My Node!"
world.addChild(myNode) // World is a higher-level node in my scene
这就是我在场景中再次检测触摸的方式:
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!)
if let touch = touches.anyObject() as? UITouch
if let shapeNode = nodeAtPoint(touch.locationInNode(self)) as? SKShapeNode
println("Touched \(shapeNode.name)")
else
println("Nothing here")
线节点显示没有问题。但是,它根本没有注册 touchesEnded。
真的,我有三个模糊不清的问题:
有没有更好的方法来创建一个 SKShapeNode,它是两点之间的一条线,而无需调用便利初始化程序?我计划子类化 SKShapeNode 以向节点添加额外的逻辑,并且子类无法访问超类的便利初始化程序。
更重要的是,如何让场景识别那里的线节点并触发 touchesEnded?
有没有办法,使用这种机制,我可以让它更“模糊”,所以它处理接近线的触摸,而不是在线?我最终的计划是让它更薄,但我仍然希望有一个大的触摸区。我想如果不出意外,我可以创建两个节点:一个清晰/厚,另一个红色/细,并在清晰的节点上处理触摸事件,但我想知道是否有更好的方法。
李>【问题讨论】:
【参考方案1】:在回答您的主要问题时,您的 touchesEnded 方法存在问题。苹果展示的模板推荐如下布局:
override func touchesEnded(touches: NSSet, withEvent event: UIEvent)
for touch: AnyObject in touches
let location = touch.locationInNode(self)
然后您可以使用此方法查看 location
值是否在行框架内(为了做到这一点,我在 didMoveToView 之外创建了“myNode”变量,以便我可以从其余部分访问它函数):
override func touchesEnded(touches: NSSet, withEvent event: UIEvent)
for touch: AnyObject in touches
let location = touch.locationInNode(world)
if CGRectContainsPoint(myNode.frame, location)
println("Touched \(myNode.name)")
else
println("Nothing here")
至于“模糊”行,您可以简单地检查一个更大的 CGRect。在上面的代码中,我检查了myNode.frame
,但您可以创建一个比行稍大的 CGRect 变量,这样您就可以检测到不直接击中它的触摸。
至于更简洁的代码,我目前想不出,但这并不是说没有办法。但是,我不太明白您所说的子类无法访问便捷方法是什么意思,因为只要您正确导入,它们就可以访问超类所做的任何事情。
我希望这会有所帮助。
【讨论】:
如何扩大到在屏幕上显示动态行数以进行检查?另外,为什么要这样做而不是抓住nodeAtPoint()
? developer.apple.com/library/ios/documentation/GraphicsAnimation/… 建议 nodeAtPoint()
确定与点相交的顶部节点是什么。
我会在初始化时命名每一行,然后枚举它们以查看有多少被点击。至于使用nodeAtPoint()
,我试过了,遇到了和你一样的问题,从来没有检测到节点。出于这个原因,我使用了 CGRectContainsPoint。
采用CGRectContainsPoint()
的方式,它会在离线不远的地方检测到触摸,因为框架是矩形,而我的线是对角线。所以它认为我正在点击“线”,因为我正在点击对角线定义的矩形。
@Reece55 我相信这种方法确实有效,但它可能无法非常准确地检测到触摸。您可能想正确地使用它,尤其是在更大的形状上以更好地测试它。它通常运行良好,没有任何问题,尽管有时线条的框架不能很好地表示实际线条本身。尽管如此,如果它对您有用,那么我很高兴能为您提供帮助!以上是关于检测 SKShapeNode 上的触摸是一条线的主要内容,如果未能解决你的问题,请参考以下文章