user2164327
user2164327

Reputation: 283

sprite kit touch userInteractionEnabled = true

hi I'm trying to have a sprite overlay set as water with alpha set to 0.3 and other sprites underneath as fishes but i can't touch the fish as the water sprite swallows the touches

from this post [iOS7 Sprite Kit how to disable touches on a sprite to make it "tap through"?
It says to subclass SKSpriteNode so after reading up on subclassing i made this https://www.dropbox.com/s/mt067syvbvkmhjb/newClass.zip?dl=0 i can't see where I'm going wrong? any help would be good cheers

my GameScene.swift

import SpriteKit
class GameScene: SKScene
{
override func didMoveToView(view: SKView)
{
  let fishsprite  = fish(imageNamed: "fish")
    fishsprite.position = CGPoint(x: 512, y:350)
    fishsprite.zPosition = 1
    fishsprite.name = "fish"
    addChild(fishsprite)

    let watersprite  = water(imageNamed: "water")
   watersprite.position = CGPoint(x: 512, y: 360)
   watersprite.zPosition = 3
    watersprite.alpha = 0.3
    watersprite.name = "Water"
    addChild(watersprite)
}

}

my water class

 import SpriteKit
 class water : SKSpriteNode
 {
required init(coder aDecoder: NSCoder)
 {
    fatalError("NSCoding not supported")
}

init(imageNamed: String) {
    let waterTexture = SKTexture(imageNamed: imageNamed)
    super.init(texture: waterTexture, color: nil, size: CGSize(width: 1024, height: 768))
    userInteractionEnabled = false // blocks the touches from everything
   // userInteractionEnabled = true //gets  the touches but stop fish getting them
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>)
    {

 //                      let location = touch.locationInNode(scene)
 //                   let touchedNode = nodeAtPoint(location)
 //                      println(touchedNode.zPosition)
 //     

    }
}

    override func touchesMoved(touches: Set<NSObject>, withEvent event:   UIEvent) {
    for touch in (touches as! Set<UITouch>)
    {

    }
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in touches
    {

    }
}

}

my fish class

  import Foundation
  import SpriteKit
   class fish : SKSpriteNode
  {
    required init(coder aDecoder: NSCoder) {
    fatalError("NSCoding not supported")
}

init(imageNamed: String)
{
    let fishTexture = SKTexture(imageNamed: imageNamed)
    super.init(texture: fishTexture, color: nil, size: fishTexture.size())
    userInteractionEnabled = true
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>)
    {
        let location = touch.locationInNode(scene)
        let touchedNode = nodeAtPoint(location)
        println(touchedNode)
        zPosition = 15
        let liftUp = SKAction.scaleTo(1.2, duration: 0.2)
        runAction(liftUp, withKey: "pickup")
        let wiggleIn = SKAction.scaleXTo(1.0, duration: 0.2)
        let wiggleOut = SKAction.scaleXTo(1.2, duration: 0.2)
        let wiggle = SKAction.sequence([wiggleIn, wiggleOut])
        let wiggleRepeat = SKAction.repeatActionForever(wiggle)
        runAction(wiggleRepeat, withKey: "wiggle")
    }
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>)
    {
        let location = touch.locationInNode(scene)
        let touchedNode = nodeAtPoint(location)
        touchedNode.position = location
        touchedNode.zPosition = 15
        println(touchedNode)
    }
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in touches
    {
        zPosition = 2
        let dropDown = SKAction.scaleTo(1.0, duration: 0.2)
        runAction(dropDown, withKey: "drop")
        removeActionForKey("wiggle")
    }
}
}      

Upvotes: 3

Views: 669

Answers (1)

Jackster
Jackster

Reputation: 41

Hey I figured out a little workaround,

Whichever node you want to tap through,

Set the name of the node "Overlay"

Now that this node stands out from other nodes underneath

You can use this code in touched began

        for touch in touches {

           let location = touch.locationInNode(self)

           var allNodesTouched = nodesAtPoint(location)

           allNodesTouched.forEach({ (nodeTouched) in

               if nodeTouched.name == "Overlay" {

                   let I = allNodesTouched.indexOf(nodeTouched)
                   allNodesTouched.removeAtIndex(I!)
            }
        })

           if let selectedNode = allNodesTouched.first {

       }
    }

Now you can use the selectedNode

Upvotes: 2

Related Questions