skip to Main Content

I have a SpriteKitNode that I want to move around my scene when I touch it and drag it.

I have a touchesBegan method that detects if the particular node I want to move is being touched:

var selectionBoxIsTouched: Bool!
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in: self.canvasScene)
            canvasScene.enumerateChildNodes(withName: "Selection_Box", using:
                                                { [self] (node, stop) -> Void in
                if self.canvasScene.atPoint(location) == node {
                    selectionBoxIsTouched = true
                } else {
                    selectionBoxIsTouched = false
                }
            })
        }
    } 

Next, I have touchesMoved method where if my node is currently being touched, it gets moved as the user moves a finger across the screen:

  
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if selectionBoxIsTouched {
            if let touch = touches.first {
                let touchLoc = touch.location(in: self.canvasScene)
                let prevTouchLoc = touch.previousLocation(in: self.canvasScene)
                
                canvasScene.enumerateChildNodes(withName: "Selection_Box", using:
                                                    { (node, stop) -> Void in
                    if let touchedNode = node as? SKShapeNode {
                        let newYPos = touchedNode.position.y + (touchLoc.y - prevTouchLoc.y)
                        let newXPos = touchedNode.position.x + (touchLoc.x - prevTouchLoc.x)
                        touchedNode.position = CGPoint(x: newXPos, y: newYPos)  //set new X and Y for your sprite.
                    }
                })
            }
        }
    }

When I select the node + try to move it, it doesn’t move in a continuous motion….it moves a small amount, then stops; even if my finger keeps moving across the screen.

How do I fix this so that the node moves in a smooth, continuous motion with my finger?

2

Answers


  1. Chosen as BEST ANSWER

    The issue ended up being that I had a pan gesture recognizer that was conflicting with the multitouch delegate methods. I fixed by adding logic to enable/disable that gesture recognizer if the particular node I wanted to move was being touched or not.


  2. this touch code should work for you

    extension GameScene {
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            for touch in touches{
                let location = touch.location(in: self)
                let _ = self.nodes(at: location).map { ($0 as? DraggableNode)?.isPicked = true }
            }
        }
        
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            for touch in touches{
                let touchLoc = touch.location(in: self)
                let prevTouchLoc = touch.previousLocation(in: self)
                let picked_nodes = self.children.filter { ($0 as? DraggableNode)?.isPicked ?? false }
                for node in picked_nodes {
                    let deltaX = touchLoc.x - prevTouchLoc.x
                    let deltaY = touchLoc.y - prevTouchLoc.y
                    node.position.x += deltaX
                    node.position.y += deltaY
                }
            }
        }
        
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            let _ = self.children.map { ($0 as? DraggableNode)?.isPicked = false }
        }
    }
    

    combined with the following SKScene. i would recommend putting your picker flag inside the movable node, that way you can drag individual nodes rather than having a single global test.

    class DraggableNode: SKNode {
        var isPicked:Bool = false
        override init() {
            super.init()
            let shape = SKShapeNode(circleOfRadius: 50)
            shape.fillColor = .red
            shape.name = "Selection_Box"
            self.addChild(shape)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class GameScene: SKScene {
        let draggableNodeA = DraggableNode()
        let draggableNodeB = DraggableNode()
    
        override func didMove(to view: SKView) {
            draggableNodeA.position.x = 50
            draggableNodeB.position.x = -50
            self.addChild(draggableNodeA)
            self.addChild(draggableNodeB)
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search