检测 SKSpriteNodes 上的触摸事件
Posted
技术标签:
【中文标题】检测 SKSpriteNodes 上的触摸事件【英文标题】:Detecting touch events on SKSpriteNodes 【发布时间】:2018-09-24 00:08:57 【问题描述】:所以这里有一些类似的问题,但他们并没有真正回答我遇到的问题。
以下对我的项目的解释可能有帮助,也可能没有帮助,我在这里添加以防万一......
我正在尝试构建我的第一个 ios 游戏,并且我已经使用场景编辑器构建了一个场景。该场景包含一个名为“World”的 SKNode。然后有一个 backgroundNode 和一个foregroundNode,它们是世界节点的子节点。现在场景中的所有东西,所有 SKSpriteNode,都是 backgroundNode 的子节点。
在我的 GameScene.swift 文件中,我将变量附加到背景和前景节点,以便我可以在游戏进行时将子节点添加到这些节点。
希望到目前为止这很清楚......
现在我在我的项目中添加了 5 个其他 *.sks 文件。这些文件包含我制作的场景,这些场景将通过我的 GameScene.swift 文件中的代码添加为前景节点的子节点。这些场景文件中的 SKSpriteNodes 放置在前景中,但它们的 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()
希望这对你们来说已经足够了......如果您需要我提供更多代码,或者需要我澄清任何事情,请告诉我
【问题讨论】:
使用 UITouch 识别精灵。 【参考方案1】:请阅读代码中的注释。你可以在 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
【讨论】:
【参考方案2】:您想使用nodesAtPoint
进行命中测试并获取与该点关联的所有节点。然后过滤列表以找到您要查找的框。
如果您有很多图层,您可能还想在图形顶部添加一个不可见的图层来处理被触摸的节点
您的另一个选择是关闭除框以外的所有内容上的isUserInteractionEnabled
,然后覆盖框的触摸事件,但这意味着您不能像现在这样使用手势。
【讨论】:
以上是关于检测 SKSpriteNodes 上的触摸事件的主要内容,如果未能解决你的问题,请参考以下文章
在 Monotouch 中的 UIPageViewController 中检测控件上的触摸事件