0

I have an SKShapeNode that I have created and given a CGPath to. This is in my GameScene.swift in didMoveToView:

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

And this is how I'm detecting touches, again in the 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")
        }
    }
}

The line node is showing up with no issues. However, it is not registering touchesEnded at all.

Really, I have three questions nebulous to this:

  1. Is there a better way to create an SKShapeNode that is a line between two points without calling a convenience initializer? I plan on subclassing SKShapeNode to add additional logic to the node, and the subclass doesn't have access to convenience initializers of the superclass.

  2. More importantly, how do I get the scene to recognize my line node there and trigger touchesEnded?

  3. Is there a way, using that mechanism, I can make it a bit more "fuzzy", so it handles touches close to the line, instead of on the line? My eventual plan is to make it thinner, but I'd still like to have a large touch zone. I figure if nothing else, I can create two nodes: one clear/thick and the other red/thin, and handle touch events on the clear one, but I would like to know if there's a better way.

4

1 回答 1

2

在回答您的主要问题时,您的 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 的变量,该变量比该行稍大,以便您可以检测到不直接击中它的触摸。

至于更简洁的代码,我目前想不出,但这并不是说没有办法。但是,我不太明白您对子类无法访问便利方法的意思是什么,因为只要您正确导入,它们就可以访问超类所做的任何事情。

我希望这有帮助。

于 2014-07-01T09:22:37.810 回答