Search code examples
swiftsprite-kitcoordinatesnodestouchesmoved

How to convert the coordinates of one SpriteNode to another that is not a child or descendant


In my SpriteKit Scene I got the following setup:

Several nodes with the name sourceNode are direct children of the scene. A node called targetNode is a child of another node called sectionNode, sectionNode is a child of the scene as well.

self --> sourceNode

self --> sectionNode --> targetNode

When using the touchesMoved method to move the sourceNode I set the position of the sourceNode to the current location of the touch. Once the touch location is above the targetNode I want to snap the sourceNode to the targetNode by matching their positions.

My issue:

I do not seem to be able to properly convert in between the two coordinate spaces. I tried different variations of convert(_:from:) and convert(_:to:), but none of it works. I know convert expects both nodes to be in the same node tree, but as both of them are descendants of the scene, aren't they considered part of the same node tree?

(If both sourceNode and targetNode are in the same coordinate system as siblings, the code works by just assigning the position of the targetNode to the position of the sourceNode)

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let touchLocation = touch.location(in: self)
        let touchedNodes = nodes(at: touchLocation)

        guard let sourceNode = touchedNodes.filter({$0.name == "sourceNode"}).first else { return }

        if let targetNode = touchedNodes.filter({$0.name == "targetNode"}).first {
            
            // sourceNode.position = targetNode.position    <-- works if both have the same parents   

            sourceNode.position = convert(targetNode.position, to: sourceNode)
        } else {
            sourceNode.position = touchLocation
        }
    }
}

Solution

  • To move/snap the sourceNode to the coordinates of the targetNode, you could do the following:

    sourceNode.move(toParent: sectionNode)
    sourceNode.position = targetNode.position
    sourceNode.move(toParent: scene)