首页 > 解决方案 > 检测 SKSpriteNodes 上的触摸事件

问题描述

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

以下对我的项目的解释可能有帮助,也可能没有帮助,我在这里添加它以防万一......

我正在尝试构建我的第一个 iOS 游戏,并且我已经使用场景编辑器构建了一个场景。该场景包含一个名为“World”的 SKNode。然后有一个 backgroundNode 和一个foregroundNode,它们是世界节点的子节点。现在场景中的所有东西,所有 SKSpriteNode,都是 backgroundNode 的子节点。

在我的 GameScene.swift 文件中,我将变量附加到背景和前景节点,以便随着游戏的进行我可以将子节点添加到这些节点。

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

现在我在我的项目中添加了 5 个其他 *.sks 文件。这些文件包含我制作的场景,这些场景将通过我的 GameScene.swift 文件中的代码添加为前景节点的子节点。这些场景文件中的 SKSpriteNode 放置在前景中,但它们的 z 位置小于背景子节点之一的 z 位置。这是因为我想让一个盒子出现在光束后面(光束是背景的一部分,盒子被添加到前景中)。这是一张图片,以防我引起任何混乱 添加到前景节点的框的图片出现在作为背景节点子节点的灯光后面

我的问题是......我想使用手势识别器点击屏幕,这样当我点击框时我可以做一些事情。麻烦的是,由于光束具有更大的 z 位置(导致我想要的效果),每次我使用 atPoint(_ p: CGPoint) -> SKNode 方法来确定我点击的节点时,我都会返回光梁节点而不是箱节点。

如何仅点击框?我已经尝试将灯的 isUserInteractionEnabled 属性更改为 false,并且我尝试使用 touchesBegan,如对类似问题的许多其他回复所示。我也尝试过阅读 Apple 提供的 swift developer 文档,但我无法弄清楚。

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

 //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()
    }
}

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

标签: iosswiftsprite-kitskspritenodeuitapgesturerecognizer

解决方案


请阅读代码中的注释。你可以在 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}
   }

推荐阅读