user6943329
user6943329

Reputation:

Nodes not moving

(Swift 3)

import SpriteKit
   import GameplayKit

   class GameScene: SKScene {
var object = SKSpriteNode()

override func didMove(to view: SKView) {

    object = self.childNode(withName: "dot") as! SKSpriteNode

}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        let location = touch.location(in: self)
        object.run(SKAction.move(to: location, duration: 0.3))

    }

}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)

        object.run(SKAction.move(to: location, duration: 0.3))


    }
}

override func update(_ currentTime: TimeInterval) {




   }
}

This code is designed to allow me to drag a "dot" around the scene, however... I just cant! It won't budge! I've looked online, but I can't find anything. I tried pasting this code into a fresh project, and it worked there, but even deleting and replacing my "dot" node doesn't seem to help on my main project.

So... any ideas?

Upvotes: 3

Views: 574

Answers (2)

Alessandro Ornano
Alessandro Ornano

Reputation: 35402

Confused has already said everything you must know about your issue. I try to add details that help you with the code. First of all, you should use optional binding when you search a node with self.childNode(withName so if this node does not exist your project does not crash. Then, as explained by Confused, you should add controls before you call your actions to be sure that your action is not already running. I make an example here below:

import SpriteKit
class GameScene: SKScene {
    var object = SKSpriteNode.init(color: .red, size: CGSize(width:100,height:100))
    override func didMove(to view: SKView) {
        if let sprite = self.childNode(withName: "//dot") as? SKSpriteNode {
            object = sprite
        } else { //dot not exist so I draw a red square..
            addChild(object)
        }
        object.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    }
    func makeMoves(_ destination: CGPoint) {
        if object.action(forKey: "objectMove") == nil {
            object.run(SKAction.move(to: destination, duration: 0.3),withKey:"objectMove")
        }
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            makeMoves(location)
        }
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            makeMoves(location)
        }
    }
}

Output:

enter image description here

Upvotes: 2

Confused
Confused

Reputation: 6288

The fact it works in a new, barebones project, and not in your fuller project indicates the problem is in the fuller project. Without a glimpse at that, it's pretty hard to tell what's actually going wrong.

Peculiar, to me, is the use of the SKAction to do the move in touchesMoved(). If you think about this in terms of how SKActions works, you're continually adding new move actions, at whatever rate the touchscreen is picking up changes in position. This is (almost always) much faster than 0.3 seconds. More like 0.016 seconds. So this should be causing all manner of problems, in its own right.

Further, you need something in the GameScene's touchesMoved() to ascertain what's being touched, and then, based on touching the dot, move it, specifically. This, I assume, is your "object".

A simpler way of doing this might be to use touchesMoved in a subclass of SKSpriteNode that represents and creates your dot instance.

Upvotes: 2

Related Questions