iosswiftsprite-kitshapesskshapenode

How to detect precisely when a SKShapeNode is touched?


I'm working with Swift and SpriteKit.

I have the following situation :

enter image description here

Here, each of the "triangles" is a SKShapenode. My problem is that I would like to detect when someone touches the screen which triangle is being touched. I assume that the hitbox of all these triangles are rectangles so my function returns me all the hitboxes touched while I only want to know which one is actually touched.

Is there any way to have a hitbox that perfectly match the shape instead of a rectangle ?

Here's my current code :

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    let touch = touches.first
    let touchPosition = touch!.locationInNode(self)
    let touchedNodes = self.nodesAtPoint(touchPosition)

    print(touchedNodes) //this should return only one "triangle" named node

    for touchedNode in touchedNodes
    {
        if let name = touchedNode.name
        {
            if name == "triangle"
            {
                let triangle = touchedNode as! SKShapeNode
                // stuff here
            }
        }
    }
}

Solution

  • You could try to use CGPathContainsPoint with a SKShapeNode instead of nodesAtPoint, which is more appropriate:

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
    {
        let touch = touches.first
        let touchPosition = touch!.locationInNode(self)
        self.enumerateChildNodesWithName("triangle") { node, _ in
            // do something with node
            if node is SKShapeNode {
                if let p = (node as! SKShapeNode).path {
                    if CGPathContainsPoint(p, nil, touchPosition, false) {
                        print("you have touched triangle: \(node.name)")
                        let triangle = node as! SKShapeNode
                        // stuff here
                    }
                }
            }
        }
    }