blue
blue

Reputation: 7375

Sprite node does not detect touches?

I need to detect whether the user has tapped a sprite node.

Here I create the sprite node:

var enemy1Texture = SKTexture(imageNamed: "enemy1")
enemy1 = SKSpriteNode(texture: enemy1Texture)
enemy1.setScale(0.3)
enemy1.position = CGPoint(x: self.size.width * 0.5, y: self.size.height * 1.2)
        self.addChild(enemy1)

Here in touchesBegan I set up the variables for detecting the touch:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)  {
        /* Called when a touch begins */

        for touch: AnyObject in touches {

            let touch = touches.first as? UITouch
            let location = touch!.locationInNode(self)
            let touchedNode = self.nodeAtPoint(location)
            let touchedNodeName = touchedNode.name

            enemy1.name = "enemy1"
            enemy1.userInteractionEnabled = true

then at the end of the function I check for the name of the touched sprite node and try to execute the corresponding code:

if touchedNodeName == "enemy1"  {
    //Enemy touched code
    println("Enemy1 was touched!")          
}

And it isn't working. When I tap on the sprite node as it moves down the screen, nothing is printed to the console. What am I doing wrong?

Upvotes: 0

Views: 940

Answers (2)

Whirlwind
Whirlwind

Reputation: 13665

I think you are using userInteractionEnabled incorrectly here. That is totally unnecessary in order to detect touches in the way you are trying to detect (in touchesBegan of the scene). I assume that touchesBegan is the method from the GameScene because the enemy1 is SKSpriteNode and not a subclass of SKSpriteNode with implemented touchesBegan method.

Using userInteractionEnabled on a node allows the node itself to receive touches. And if you decide to do that, you need to implement touchesBegan: on that particular object (as I said above, you have to subclass SKSpriteNode). But I guess that is not a situation here and not what you want. Note that nodeAtPoint is based on touch location (scene receives touches by default), and it will tell you is there any node at certain location, it doesn't care if that node receives touches.

So, from the code you've posted, I would say that you have to set node's name correctly in order check for it in touchesBegan method. Just name your node in didMoveToView method, right after you create the enemy, because currently you are trying to use node.name which looks like it's not set yet.

Upvotes: 1

jparaskakis
jparaskakis

Reputation: 133

At the Point you create the touchedNodeName variable the name of the enemy1 Node does not have a Name attribute set. Move the

enemy1.name = "enemy1"

at the creation of the Node right after

enemy1 = SKSpriteNode(texture: enemy1Texture)

so it becomes

enemy1 = SKSpriteNode(texture: enemy1Texture)
enemy1.name = "enemy1"

Then when you get touchedNode.name you can check if it is "enemy1" or not

NB.: Be careful if you are trying to access the .Name attribute in every touch you should assign a Name to every Node in your Scene or it will be nil. Or you can check

if(touchedNode.Name != nil){
     //Then get the .Name variable and perform your checks
}

In another approach you can check if the Node that you pressed is the enemy1 Node but the Node should be visible in the touchesBegan function like this

if(touchedNode == enemy1){
    //Your code here
}

Upvotes: 1

Related Questions