3

So I am super new to swift and iOS development but not totally new to programming, and was just going through some tutorials, but basically my code looks like this:

import SpriteKit


class GameScene: SKScene {


override func didMoveToView(view: SKView) {
    let circle = SKShapeNode(circleOfRadius: 30.0)
    circle.position = CGPointMake(100, 200)
    addChild(circle)
}

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        let location = touch.locationInNode(self)
        let touchedNode = nodeAtPoint(location)
        touchedNode.position = location;
    }
}

}

When I build this it recognizes and moves the circle when I drag it, but only for about 30 pixels and then I have to touch it again to move it. What am I doing wrong here?

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Joe B
  • 81
  • 7
  • does your finger leave the screen at any point? Is there maybe another node (ie you get yours via nodeAtPoint every time the touch moves) that intercepts the touch and moves instead? – CodeSmile Jan 27 '15 at 17:29
  • No, I tried this with some code for debugging that would tell me if I was touching the background and it never did. Is there a better way to do this than the nodeAtPoint? Thanks for your help and the quick response – Joe B Jan 27 '15 at 17:34

2 Answers2

3

I might be wrong but I believe your finger is leaving the node limits and enters the background. I would set it up as such:

// First make the shape available throughout the code and make sure you have a place to save the touch event for later use.
var circle: SKShapeNode!
var circleTouch: UITouch?

// Create the Shape
override func didMoveToView(view: SKView) {
    circle = SKShapeNode(circleOfRadius: 30.0)
    circle.position = CGPointMake(100, 200)
    addChild(circle)
}

// When a finger is placed on the screen, check if it's in the circle, if it is, keep that touch even in memory so we can reference it later because other fingers could touch other things in the scene.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if nodeAtPoint(touch.locationInNode(self)) == circle {
            circleTouch = touch as? UITouch
        }
    }
}

// Check if the touch event that is moving is the one that anchored the circle to our finger, if yes, move the circle to the position of the finger.
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if circleTouch != nil {
            if touch as UITouch == circleTouch! {
                let location = touch.locationInNode(self)
                circle.position = location
            }
        }
    }
}

// Clean up the touch event when the finger anchoring the circle is raised from the screen.
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if circleTouch != nil {
            if touch as UITouch == circleTouch! {
                circleTouch = nil
            }
        }
    }
}

You can also use if let statements in there but I checked for nil instead for clarity.

Tokuriku
  • 1,332
  • 13
  • 22
1

Tokuriku, thanks so much, you we're not quite right but it got me to the eventual answer, here it is

import SpriteKit

class GameScene: SKScene {
var circleTouch: UITouch?

override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    let circle = SKShapeNode(circleOfRadius: 40.0)
    circle.fillColor = UIColor.blackColor()
    circle.position = CGPoint(x: size.width * 0.5, y: size.height * 0.2)
    circle.name = "userCircle"
    addChild(circle)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if nodeAtPoint(touch.locationInNode(self)).name == "userCircle" {
            circleTouch = touch as? UITouch
        }
    }
}

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if circleTouch != nil {
            if touch as UITouch == circleTouch! {
                let location = touch.locationInNode(self)
                let touchedNode = nodeAtPoint(location)
                touchedNode.position = location
            }
        }
    }
}

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    for touch in touches {
        if circleTouch != nil {
            if touch as UITouch == circleTouch! {
                circleTouch = nil
            }
        }
    }
}
Joe B
  • 81
  • 7