TimurTim
TimurTim

Reputation: 191

How to drag a SKSpriteNode without touching it with Swift

I'm trying to move SKSpriteNode horizontally by dragging. To get the idea of what I try to achieve you can watch this. I want player to be able to drag sprite without touching it. But I don't really know how to implement it correctly. I tried to do something like:

 override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    capLeft.size = self.capLeft.size
    self.capLeft.position = CGPointMake(CGRectGetMinX(self.frame) + self.capLeft.size.height * 2, CGRectGetMinY(self.frame) + self.capLeft.size.height * 1.5)
    capLeft.zPosition = 1

    self.addChild(capLeft)

    let panLeftCap: UIPanGestureRecognizer = UIPanGestureRecognizer(target: capLeft, action: Selector("moveLeftCap:"))

And when I'm setting a moveLeftCap function, code that I've found for UIPanGestureRecognizer is requiring "View" and gives me an error. I also wanted to limit min and max positions of a sprite through which it shouldn't go. Any ideas how to implement that?

Upvotes: 3

Views: 1138

Answers (1)

dennism
dennism

Reputation: 513

You probably get that error because you can't just access the view from any node in the tree. You could to refer to it as scene!.view or you handle the gesture within you scene instead which is preferable if you want to keep things simple.

I gave it a try and came up with this basic scene:

import SpriteKit

class GameScene: SKScene {

    var shape:SKNode!

    override func didMoveToView(view: SKView) {
        //creates the shape to be moved
        shape = SKShapeNode(circleOfRadius: 30.0)
        shape.position = CGPointMake(frame.midX, frame.midY)
        addChild(shape)

        //sets up gesture recognizer
        let pan = UIPanGestureRecognizer(target: self, action: "panned:")
        view.addGestureRecognizer(pan)
    }

    var previousTranslateX:CGFloat = 0.0

    func panned (sender:UIPanGestureRecognizer) {
        //retrieve pan movement along the x-axis of the view since the gesture began
        let currentTranslateX = sender.translationInView(view!).x

        //calculate translation since last measurement
        let translateX = currentTranslateX - previousTranslateX

        //move shape within frame boundaries
        let newShapeX = shape.position.x + translateX
        if newShapeX < frame.maxX && newShapeX > frame.minX {
            shape.position = CGPointMake(shape.position.x + translateX, shape.position.y)
        }

        //(re-)set previous measurement
        if sender.state == .Ended {
        previousTranslateX = 0
        } else {
            previousTranslateX = currentTranslateX
        }
    }
}

when you move you finger across the screen, the circle gets moves along the x-axis accordingly.

if you want to move the sprite in both x and y directions, remember to invert the y-values from the view (up in view is down in scene).

Upvotes: 2

Related Questions