ios - 检测 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()
}
}
希望这对你们来说已经足够了......如果您需要我提供更多代码,或者需要我澄清任何事情,请告诉我
解决方案
请阅读代码中的注释。你可以在 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}
}
推荐阅读
- python - How to reference a file relative to the original script?
- regex - 为什么我的正则表达式只给我一个组?
- c++ - Running PiCamera on Ubuntu in C++
- android - How to find LatLng bound for an area in google maps?
- excel - Index with counta and if?
- google-apps-script - 脚本无法打开文档(无法访问,请重试)
- c - 将带有 glut 的点击坐标添加到向量的链接列表中
- python - tkinter NavigationToolbar2Tk with matplotlib disappears
- while-loop - ZSH script exits even though ERR_EXIT is off
- python - 检查python中dict中的键值是否相同