在SKSpriteNodes上检测触摸事件

时间:2018-09-24 00:08:57

标签: ios swift sprite-kit skspritenode uitapgesturerecognizer

所以这里有一些类似的问题,但是它们并不能真正回答我遇到的问题/问题。

以下对我的项目的解释可能有帮助,也可能无济于事,以防万一...

我正在尝试构建我的第一个iOS游戏,并且已经使用场景编辑器构建了一个场景。该场景包含一个名为“ World”的SKNode。然后有一个world节点的子节点backgroundNode和前景节点Node。现在场景中的所有内容,所有SKSpriteNodes,都是backgroundNode的子代。

在我的GameScene.swift文件中,我在后台节点和前景节点上附加了变量,以便可以在游戏进行时向这些节点添加子级。

希望到目前为止,这很清楚...

现在,我已经向项目添加了另外5个* .sks文件。这些文件包含我制作的场景,这些场景将通过GameScene.swift文件中的代码添加为前景节点的子级。这些场景文件中的SKSpriteNodes放置在前景中,但是它们的z位置小于背景子节点之一的z位置。这是因为我要在光束后面显示一个框(光束位于背景之外,并且框已添加到前景)。这是一张图片,以防万一我感到困惑 Picture Of Boxes that were added to the foreground node appearing behind the lights that are children of the background node

我的问题是这个... 我想使用手势识别器在屏幕上点击,以便在点击框时可以执行一些操作。麻烦的是,由于光束具有较大的z位置(由于我想要的效果),所以每次我使用atPoint(_ p:CGPoint)-> SKNode方法来确定我点击的哪个节点时,我都会返回光梁节点而不是箱形节点。

如何仅点击框?我已经尝试将灯的isUserInteractionEnabled属性更改为false,并且尝试使用touchesBegan,如对类似问题的许多其他响应所示。我也曾尝试阅读Apple提供的快速开发人员文档,但我不知道这一点。

我的手势识别器的代码如下:

 //variables for gesture recognition
let tapGesture = UITapGestureRecognizer()
let swipeUpGesture = UISwipeGestureRecognizer()

//set up the tap gesture recognizer
tapGesture.addTarget(self, action: #selector(GameScene.tappedBox(_:)))
self.view!.addGestureRecognizer(tapGesture)
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1

//handles the tap event on the screen
@objc func tappedBox(_ recognizer: UITapGestureRecognizer) {

    //gets the location of the touch
    let touchLocation = recognizer.location(in: recognizer.view)
    if TESTING_TAP {
        print("The touched location is: \(touchLocation)")
    }

    //enumerates through the scenes children to see if the box I am trying to tap on can be detected (It can be detected using this just don't know how to actually detect it by tapping on the box)
    enumerateChildNodes(withName: "//Box1", using: { node, _ in
        print("We have found a single box node")
    })

    //tells me what node is returned at the tapped location
    let touchedNode = atPoint(touchLocation)
    print("The node touched was: \(String(describing: touchedNode.name))")

    //chooses which animation to run based on the game and player states
    if gameState == .waitingForTap && playerState == .idle{
        startRunning()              //starts the running animation
        unPauseAnimation()
    }else if gameState == .waitingForTap && playerState == .running {
        standStill()                //makes the player stand still
        unPauseAnimation()
    }
}

希望这对你们来说足够了...如果您需要我提供更多代码,或者需要我澄清任何内容,请告诉我

2 个答案:

答案 0 :(得分:2)

请阅读代码中的注释。您可以在spriteKit中轻松获得所需的内容。希望你能得到答案。

     @objc func tappedBox(_ recognizer: UITapGestureRecognizer) {

     let touchLocation = recognizer.location(in: recognizer.view)

  // Before you check the position, you need to convert the location from view to Scene. That's the right location.
     let point =  (recognizer.view as! SKView).convert(touchLocation, to: self)

      print ( getNodesatPoint(point, withName: "whatever Node name"  ) )
   }

 // 2 : This function  gives you all nodes with the name you assign. If you node has a unique name, you got it.
 ///     You can change name to other properties and find out.

     private func   getNodesatPoint(_ point : CGPoint , withName name: String) -> [SKNode] {
           return self.nodes(at: point).filter{ $0.name == name}
   }

答案 1 :(得分:0)

您要使用nodesAtPoint进行命中测试,并获取与该点关联的所有节点。然后过滤列表以找到所需的框。

如果要处理的图层很多,您可能还想在图形上方添加一个不可见的图层来处理被触摸的节点

您的另一个选择是关闭除框以外的所有内容的isUserInteractionEnabled,然后覆盖框的触摸事件,但这意味着您不能像现在一样使用手势。