touchesBegan,如何获取所有触摸点而不仅仅是第一个或最后一个?

5

在SpriteKit中的SKSpriteNodes和其他可见节点上,对这些节点的触摸响应通常以以下某种方式完成:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first {...
 // do something with the touch location that's now in touch
// etc

这很棒,但如果我想确保获取此(假设为...)SKSpriteNode内部所有触摸的触摸信息怎么办?
= touches.first 限制条件仅响应此 SKSpriteNode 内第一个触摸。如何对此 SKSpriteNode 中的所有触摸执行此操作,以便每个触摸都有其位置可用,或者它携带的和周围的任何其他信息。
我知道。愚蠢的问题。我就是那个人。我简单地无法看出如何做到这一点。

我们谈论了阅读文档并理解每一行代码的实践,这就是“变得方便”的地方。'touches.first' 返回第一个触摸,因此您应该问'什么是touches?' 然后当您查看方法签名时,您将看到'touches'是一个'Set<UITouch>'。当您在Xcode中用工具提示alt-click 'touch'时,也会看到这一点。现在你的问题是“如何访问集合中的每个成员”,因此可以前往Swift文档和集合参考中的'Set'信息。练习询问此类问题 :-) - Steve Ives
缺少:"最好的方法是什么?","最有效率的方式是什么?","最灵活的方式是什么?" 和其他我不敢在SO上问但想要得到答案的主观性问题。我知道这是一个Set,来自于 Set<UITouch>,我知道如何通过 for loop 访问 Set 的内容... 但是肯定这不是处理触摸事件这么重要的事情的最佳/正确/灵活的方式,对吧?!@SteveIves。然后还需要使用 multipleTouchEnabled,这只有通过试错才能学到。还有其他具有相同问题的人,那些跟随者。 - Confused
但最让我烦恼的是,所有应该/可以/将会与使用SpriteKit有关的事物的文档(如果苹果公司关心它并且有很多用户),最多也只是简单的概述。 - Confused
2个回答

10

通常情况下,除非将 multipleTouchEnabled 属性设置为 true,否则视图不会响应多点触摸。

mySprite.multipleTouchEnabled = true
你会注意到方法touchesBegan:event:不返回一个单独的UITouch对象,而是一组(也称为无序集合)UITouch对象。
在这个方法内部,你可以(例如)迭代这个集合,以便检查每个触摸上的条件,而不仅仅是获取集合中的第一个触摸。
for touch in touches {
  // do something with the touch object
  print(touch.location(mySKNodeObject))
}

这是答案 - Fluidity
这就是全部了吗?@Fluidity 没有更好的,更精确的吗?难道没有更加完美和有目的性的东西吗? - Confused
不要再没有更多信息了。有无限的例子。@Confused 如果你理解了集合的工作原理,那么你就会知道如何使用一组触摸。你想用所有这些触摸做什么?因为它们是一个集合,所以没有办法在迭代中获取它们。 - Fluidity
我们需要从你这里获得更多上下文信息。 - Fluidity
哦,等等,你想要特定于一个节点。我可以写第二个答案来展示这一点,@Confused,但是这里有很多例子。搜索文档或在这里搜索:“子类化sknode”和“覆盖sknode touchesBegan”。 - Fluidity
@Confused SKScene _是_一个SKNode,因此如果您对SKNode进行子类化,可以为其提供自己的touches__函数...独立于您的SKScene的主要函数之外....每个节点都可以成为具有自己的touches__方法的单独层。 - Fluidity

2
除了Commscheck的回答之外,以下是如何检查节点是否在特定位置的方法:
for _touch in touches {
   let aTouch = _touch.location(in: self)
   if nodes(at: aTouch).contains(desiredNode) {
     print("desired node found")
     desireNode.doSomething()

     // You can also do, 
     // if desiredNode.contains(aTouch) {
   }
}

使用SKScene.nodes,然后使用.contains,因为nodes是一个数组;SKScene继承自SKEffectsNode,后者又继承自SKNode。在导航器中单击顶部的SKScene,或显示类层次结构,您可以追踪这个nodes一直到它的起源...
你可以输入“SKScene”,然后“.”来查看所有成员及其正确的实现方式。
此外,如果您经常只需要对一个特定的节点执行操作,则可以子类化SKNode(创建自己的自定义节点),然后覆盖其touches_方法。
这里有很多好的答案展示如何做到这一点 :)

这真的很有帮助,解决了我的菜单按钮触摸状态的问题,而你们对那个问题却咸咸酥酥且不爽;) - Confused
呵呵 @困惑的 我看到你终于给我的答案点了个赞 :P 或许现在我也能像你一样负担得起悬赏了。谢谢 - Fluidity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接