Search code examples
swiftsprite-kitios8skspritenodesknode

Dragging and dropping sprites without hardcoding names using swift


I'm just trying to have the user drag and drop certain sprites around the screen. The answers I saw for this are checking the name of the sprite (something like below). There must be a better way to do this. Thanks for any input.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    var nodeTouched = SKNode()
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)

        nodeTouched = self.nodeAtPoint(location)

        if(nodeTouched.name? == "character") {
            character.position=location
            currentNodeTouched = nodeTouched
        } else {
            currentNodeTouched.name = ""
        }
    }
}

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)
        var nodeTouched = SKNode()
        nodeTouched = self.nodeAtPoint(location)

        if(currentNodeTouched.name == "character") {
            character.position = location
        }
    }
}

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)

        var nodeTouched = SKNode()
        nodeTouched = self.nodeAtPoint(location)

        if(currentNodeTouched.name == "character") {
            character.position = location
        }
    }
}

Solution

  • Since you want to drag and drop only specific sprites, there has to be a way of identifying them. This can be anything that can be used to distinguish the nodes. The following are a few suggestions on what can be used in this context.

    The code in the answer is in Objective-C, hope you can translate it to Swift.

    The name property

    As you said, this is the most commonly used way of determining whether the sprite can be dragged or not.

    The userData property

    This is a property associated with SKNode which lets you set any custom data you want. You can read about it here.

    [node.userData setValue:@(YES) forKey:@"draggable"]; //Setting the value
    
    if ([[node.userData valueForKey:@"draggable"] boolValue]) //Checking the value
    

    Subclassing

    You can also create a custom class which can either handle the deag-drop functionality on it's own or implement a BOOL as a property which can be checked in the touch delegates.

    Class name

    In some cases, you might want only the nodes of a specific class to be dragged.

    if ([node isKindOfClass:[CustomNode class]])
    
    if ([(NSStringFromClass([node class]) isEqualToString:@"CustomNode"])